Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-- llvm/Support/FormattedStream.h - Formatted streams ------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file contains raw_ostream implementations for streams to do
  10. // things like pretty-print comments.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H
  15. #define LLVM_SUPPORT_FORMATTEDSTREAM_H
  16.  
  17. #include "llvm/ADT/SmallString.h"
  18. #include "llvm/Support/raw_ostream.h"
  19. #include <utility>
  20.  
  21. namespace llvm {
  22.  
  23. /// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track
  24. /// of line and column position, allowing padding out to specific column
  25. /// boundaries and querying the number of lines written to the stream. This
  26. /// assumes that the contents of the stream is valid UTF-8 encoded text. This
  27. /// doesn't attempt to handle everything Unicode can do (combining characters,
  28. /// right-to-left markers, etc), but should cover the cases likely to appear in
  29. /// source code or diagnostic messages.
  30. class formatted_raw_ostream : public raw_ostream {
  31.   /// TheStream - The real stream we output to. We set it to be
  32.   /// unbuffered, since we're already doing our own buffering.
  33.   ///
  34.   raw_ostream *TheStream;
  35.  
  36.   /// Position - The current output column and line of the data that's
  37.   /// been flushed and the portion of the buffer that's been
  38.   /// scanned.  The line and column scheme is zero-based.
  39.   ///
  40.   std::pair<unsigned, unsigned> Position;
  41.  
  42.   /// Scanned - This points to one past the last character in the
  43.   /// buffer we've scanned.
  44.   ///
  45.   const char *Scanned;
  46.  
  47.   /// PartialUTF8Char - Either empty or a prefix of a UTF-8 code unit sequence
  48.   /// for a Unicode scalar value which should be prepended to the buffer for the
  49.   /// next call to ComputePosition. This is needed when the buffer is flushed
  50.   /// when it ends part-way through the UTF-8 encoding of a Unicode scalar
  51.   /// value, so that we can compute the display width of the character once we
  52.   /// have the rest of it.
  53.   SmallString<4> PartialUTF8Char;
  54.  
  55.   void write_impl(const char *Ptr, size_t Size) override;
  56.  
  57.   /// current_pos - Return the current position within the stream,
  58.   /// not counting the bytes currently in the buffer.
  59.   uint64_t current_pos() const override {
  60.     // Our current position in the stream is all the contents which have been
  61.     // written to the underlying stream (*not* the current position of the
  62.     // underlying stream).
  63.     return TheStream->tell();
  64.   }
  65.  
  66.   /// ComputePosition - Examine the given output buffer and figure out the new
  67.   /// position after output. This is safe to call multiple times on the same
  68.   /// buffer, as it records the most recently scanned character and resumes from
  69.   /// there when the buffer has not been flushed.
  70.   void ComputePosition(const char *Ptr, size_t size);
  71.  
  72.   /// UpdatePosition - scan the characters in [Ptr, Ptr+Size), and update the
  73.   /// line and column numbers. Unlike ComputePosition, this must be called
  74.   /// exactly once on each region of the buffer.
  75.   void UpdatePosition(const char *Ptr, size_t Size);
  76.  
  77.   void setStream(raw_ostream &Stream) {
  78.     releaseStream();
  79.  
  80.     TheStream = &Stream;
  81.  
  82.     // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
  83.     // own buffering, and it doesn't need or want TheStream to do another
  84.     // layer of buffering underneath. Resize the buffer to what TheStream
  85.     // had been using, and tell TheStream not to do its own buffering.
  86.     if (size_t BufferSize = TheStream->GetBufferSize())
  87.       SetBufferSize(BufferSize);
  88.     else
  89.       SetUnbuffered();
  90.     TheStream->SetUnbuffered();
  91.  
  92.     Scanned = nullptr;
  93.   }
  94.  
  95. public:
  96.   /// formatted_raw_ostream - Open the specified file for
  97.   /// writing. If an error occurs, information about the error is
  98.   /// put into ErrorInfo, and the stream should be immediately
  99.   /// destroyed; the string will be empty if no error occurred.
  100.   ///
  101.   /// As a side effect, the given Stream is set to be Unbuffered.
  102.   /// This is because formatted_raw_ostream does its own buffering,
  103.   /// so it doesn't want another layer of buffering to be happening
  104.   /// underneath it.
  105.   ///
  106.   formatted_raw_ostream(raw_ostream &Stream)
  107.       : TheStream(nullptr), Position(0, 0) {
  108.     setStream(Stream);
  109.   }
  110.   explicit formatted_raw_ostream() : TheStream(nullptr), Position(0, 0) {
  111.     Scanned = nullptr;
  112.   }
  113.  
  114.   ~formatted_raw_ostream() override {
  115.     flush();
  116.     releaseStream();
  117.   }
  118.  
  119.   /// PadToColumn - Align the output to some column number.  If the current
  120.   /// column is already equal to or more than NewCol, PadToColumn inserts one
  121.   /// space.
  122.   ///
  123.   /// \param NewCol - The column to move to.
  124.   formatted_raw_ostream &PadToColumn(unsigned NewCol);
  125.  
  126.   unsigned getColumn() {
  127.     // Calculate current position, taking buffer contents into account.
  128.     ComputePosition(getBufferStart(), GetNumBytesInBuffer());
  129.     return Position.first;
  130.   }
  131.  
  132.   unsigned getLine() {
  133.     // Calculate current position, taking buffer contents into account.
  134.     ComputePosition(getBufferStart(), GetNumBytesInBuffer());
  135.     return Position.second;
  136.   }
  137.  
  138.   raw_ostream &resetColor() override {
  139.     TheStream->resetColor();
  140.     return *this;
  141.   }
  142.  
  143.   raw_ostream &reverseColor() override {
  144.     TheStream->reverseColor();
  145.     return *this;
  146.   }
  147.  
  148.   raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override {
  149.     TheStream->changeColor(Color, Bold, BG);
  150.     return *this;
  151.   }
  152.  
  153.   bool is_displayed() const override {
  154.     return TheStream->is_displayed();
  155.   }
  156.  
  157. private:
  158.   void releaseStream() {
  159.     // Transfer the buffer settings from this raw_ostream back to the underlying
  160.     // stream.
  161.     if (!TheStream)
  162.       return;
  163.     if (size_t BufferSize = GetBufferSize())
  164.       TheStream->SetBufferSize(BufferSize);
  165.     else
  166.       TheStream->SetUnbuffered();
  167.   }
  168. };
  169.  
  170. /// fouts() - This returns a reference to a formatted_raw_ostream for
  171. /// standard output.  Use it like: fouts() << "foo" << "bar";
  172. formatted_raw_ostream &fouts();
  173.  
  174. /// ferrs() - This returns a reference to a formatted_raw_ostream for
  175. /// standard error.  Use it like: ferrs() << "foo" << "bar";
  176. formatted_raw_ostream &ferrs();
  177.  
  178. /// fdbgs() - This returns a reference to a formatted_raw_ostream for
  179. /// debug output.  Use it like: fdbgs() << "foo" << "bar";
  180. formatted_raw_ostream &fdbgs();
  181.  
  182. } // end llvm namespace
  183.  
  184.  
  185. #endif
  186.