LLVM API Documentation

FormattedStream.h
Go to the documentation of this file.
00001 //===-- llvm/Support/FormattedStream.h - Formatted streams ------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains raw_ostream implementations for streams to do
00011 // things like pretty-print comments.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H
00016 #define LLVM_SUPPORT_FORMATTEDSTREAM_H
00017 
00018 #include "llvm/Support/raw_ostream.h"
00019 #include <utility>
00020 
00021 namespace llvm {
00022 
00023 /// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track
00024 /// of line and column position, allowing padding out to specific column
00025 /// boundaries and querying the number of lines written to the stream.
00026 ///
00027 class formatted_raw_ostream : public raw_ostream {
00028 public:
00029   /// DELETE_STREAM - Tell the destructor to delete the held stream.
00030   ///
00031   static const bool DELETE_STREAM = true;
00032 
00033   /// PRESERVE_STREAM - Tell the destructor to not delete the held
00034   /// stream.
00035   ///
00036   static const bool PRESERVE_STREAM = false;
00037 
00038 private:
00039   /// TheStream - The real stream we output to. We set it to be
00040   /// unbuffered, since we're already doing our own buffering.
00041   ///
00042   raw_ostream *TheStream;
00043 
00044   /// DeleteStream - Do we need to delete TheStream in the
00045   /// destructor?
00046   ///
00047   bool DeleteStream;
00048 
00049   /// Position - The current output column and line of the data that's
00050   /// been flushed and the portion of the buffer that's been
00051   /// scanned.  The line and column scheme is zero-based.
00052   ///
00053   std::pair<unsigned, unsigned> Position;
00054 
00055   /// Scanned - This points to one past the last character in the
00056   /// buffer we've scanned.
00057   ///
00058   const char *Scanned;
00059 
00060   void write_impl(const char *Ptr, size_t Size) override;
00061 
00062   /// current_pos - Return the current position within the stream,
00063   /// not counting the bytes currently in the buffer.
00064   uint64_t current_pos() const override {
00065     // Our current position in the stream is all the contents which have been
00066     // written to the underlying stream (*not* the current position of the
00067     // underlying stream).
00068     return TheStream->tell();
00069   }
00070 
00071   /// ComputePosition - Examine the given output buffer and figure out the new
00072   /// position after output.
00073   ///
00074   void ComputePosition(const char *Ptr, size_t size);
00075 
00076 public:
00077   /// formatted_raw_ostream - Open the specified file for
00078   /// writing. If an error occurs, information about the error is
00079   /// put into ErrorInfo, and the stream should be immediately
00080   /// destroyed; the string will be empty if no error occurred.
00081   ///
00082   /// As a side effect, the given Stream is set to be Unbuffered.
00083   /// This is because formatted_raw_ostream does its own buffering,
00084   /// so it doesn't want another layer of buffering to be happening
00085   /// underneath it.
00086   ///
00087   formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) 
00088     : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
00089     setStream(Stream, Delete);
00090   }
00091   explicit formatted_raw_ostream()
00092     : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
00093     Scanned = nullptr;
00094   }
00095 
00096   ~formatted_raw_ostream() {
00097     flush();
00098     releaseStream();
00099   }
00100 
00101   void setStream(raw_ostream &Stream, bool Delete = false) {
00102     releaseStream();
00103 
00104     TheStream = &Stream;
00105     DeleteStream = Delete;
00106 
00107     // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
00108     // own buffering, and it doesn't need or want TheStream to do another
00109     // layer of buffering underneath. Resize the buffer to what TheStream
00110     // had been using, and tell TheStream not to do its own buffering.
00111     if (size_t BufferSize = TheStream->GetBufferSize())
00112       SetBufferSize(BufferSize);
00113     else
00114       SetUnbuffered();
00115     TheStream->SetUnbuffered();
00116 
00117     Scanned = nullptr;
00118   }
00119 
00120   /// PadToColumn - Align the output to some column number.  If the current
00121   /// column is already equal to or more than NewCol, PadToColumn inserts one
00122   /// space.
00123   ///
00124   /// \param NewCol - The column to move to.
00125   formatted_raw_ostream &PadToColumn(unsigned NewCol);
00126 
00127   /// getColumn - Return the column number
00128   unsigned getColumn() { return Position.first; }
00129 
00130   /// getLine - Return the line number
00131   unsigned getLine() { return Position.second; }
00132 
00133   raw_ostream &resetColor() override {
00134     TheStream->resetColor();
00135     return *this;
00136   }
00137 
00138   raw_ostream &reverseColor() override {
00139     TheStream->reverseColor();
00140     return *this;
00141   }
00142 
00143   raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override {
00144     TheStream->changeColor(Color, Bold, BG);
00145     return *this;
00146   }
00147 
00148   bool is_displayed() const override {
00149     return TheStream->is_displayed();
00150   }
00151 
00152 private:
00153   void releaseStream() {
00154     // Delete the stream if needed. Otherwise, transfer the buffer
00155     // settings from this raw_ostream back to the underlying stream.
00156     if (!TheStream)
00157       return;
00158     if (DeleteStream)
00159       delete TheStream;
00160     else if (size_t BufferSize = GetBufferSize())
00161       TheStream->SetBufferSize(BufferSize);
00162     else
00163       TheStream->SetUnbuffered();
00164   }
00165 };
00166 
00167 /// fouts() - This returns a reference to a formatted_raw_ostream for
00168 /// standard output.  Use it like: fouts() << "foo" << "bar";
00169 formatted_raw_ostream &fouts();
00170 
00171 /// ferrs() - This returns a reference to a formatted_raw_ostream for
00172 /// standard error.  Use it like: ferrs() << "foo" << "bar";
00173 formatted_raw_ostream &ferrs();
00174 
00175 /// fdbgs() - This returns a reference to a formatted_raw_ostream for
00176 /// debug output.  Use it like: fdbgs() << "foo" << "bar";
00177 formatted_raw_ostream &fdbgs();
00178 
00179 } // end llvm namespace
00180 
00181 
00182 #endif