Home | History | Annotate | Download | only in Support
      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 
     15 #ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H
     16 #define LLVM_SUPPORT_FORMATTEDSTREAM_H
     17 
     18 #include "llvm/Support/raw_ostream.h"
     19 
     20 namespace llvm
     21 {
     22   /// formatted_raw_ostream - Formatted raw_fd_ostream to handle
     23   /// asm-specific constructs.
     24   ///
     25   class formatted_raw_ostream : public raw_ostream {
     26   public:
     27     /// DELETE_STREAM - Tell the destructor to delete the held stream.
     28     ///
     29     static const bool DELETE_STREAM = true;
     30 
     31     /// PRESERVE_STREAM - Tell the destructor to not delete the held
     32     /// stream.
     33     ///
     34     static const bool PRESERVE_STREAM = false;
     35 
     36   private:
     37     /// TheStream - The real stream we output to. We set it to be
     38     /// unbuffered, since we're already doing our own buffering.
     39     ///
     40     raw_ostream *TheStream;
     41 
     42     /// DeleteStream - Do we need to delete TheStream in the
     43     /// destructor?
     44     ///
     45     bool DeleteStream;
     46 
     47     /// ColumnScanned - The current output column of the data that's
     48     /// been flushed and the portion of the buffer that's been
     49     /// scanned.  The column scheme is zero-based.
     50     ///
     51     unsigned ColumnScanned;
     52 
     53     /// Scanned - This points to one past the last character in the
     54     /// buffer we've scanned.
     55     ///
     56     const char *Scanned;
     57 
     58     virtual void write_impl(const char *Ptr, size_t Size);
     59 
     60     /// current_pos - Return the current position within the stream,
     61     /// not counting the bytes currently in the buffer.
     62     virtual uint64_t current_pos() const {
     63       // This has the same effect as calling TheStream.current_pos(),
     64       // but that interface is private.
     65       return TheStream->tell() - TheStream->GetNumBytesInBuffer();
     66     }
     67 
     68     /// ComputeColumn - Examine the given output buffer and figure out which
     69     /// column we end up in after output.
     70     ///
     71     void ComputeColumn(const char *Ptr, size_t size);
     72 
     73   public:
     74     /// formatted_raw_ostream - Open the specified file for
     75     /// writing. If an error occurs, information about the error is
     76     /// put into ErrorInfo, and the stream should be immediately
     77     /// destroyed; the string will be empty if no error occurred.
     78     ///
     79     /// As a side effect, the given Stream is set to be Unbuffered.
     80     /// This is because formatted_raw_ostream does its own buffering,
     81     /// so it doesn't want another layer of buffering to be happening
     82     /// underneath it.
     83     ///
     84     formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
     85       : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
     86       setStream(Stream, Delete);
     87     }
     88     explicit formatted_raw_ostream()
     89       : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
     90       Scanned = 0;
     91     }
     92 
     93     ~formatted_raw_ostream() {
     94       flush();
     95       releaseStream();
     96     }
     97 
     98     void setStream(raw_ostream &Stream, bool Delete = false) {
     99       releaseStream();
    100 
    101       TheStream = &Stream;
    102       DeleteStream = Delete;
    103 
    104       // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
    105       // own buffering, and it doesn't need or want TheStream to do another
    106       // layer of buffering underneath. Resize the buffer to what TheStream
    107       // had been using, and tell TheStream not to do its own buffering.
    108       if (size_t BufferSize = TheStream->GetBufferSize())
    109         SetBufferSize(BufferSize);
    110       else
    111         SetUnbuffered();
    112       TheStream->SetUnbuffered();
    113 
    114       Scanned = 0;
    115     }
    116 
    117     /// PadToColumn - Align the output to some column number.  If the current
    118     /// column is already equal to or more than NewCol, PadToColumn inserts one
    119     /// space.
    120     ///
    121     /// \param NewCol - The column to move to.
    122     formatted_raw_ostream &PadToColumn(unsigned NewCol);
    123 
    124   private:
    125     void releaseStream() {
    126       // Delete the stream if needed. Otherwise, transfer the buffer
    127       // settings from this raw_ostream back to the underlying stream.
    128       if (!TheStream)
    129         return;
    130       if (DeleteStream)
    131         delete TheStream;
    132       else if (size_t BufferSize = GetBufferSize())
    133         TheStream->SetBufferSize(BufferSize);
    134       else
    135         TheStream->SetUnbuffered();
    136     }
    137   };
    138 
    139 /// fouts() - This returns a reference to a formatted_raw_ostream for
    140 /// standard output.  Use it like: fouts() << "foo" << "bar";
    141 formatted_raw_ostream &fouts();
    142 
    143 /// ferrs() - This returns a reference to a formatted_raw_ostream for
    144 /// standard error.  Use it like: ferrs() << "foo" << "bar";
    145 formatted_raw_ostream &ferrs();
    146 
    147 /// fdbgs() - This returns a reference to a formatted_raw_ostream for
    148 /// debug output.  Use it like: fdbgs() << "foo" << "bar";
    149 formatted_raw_ostream &fdbgs();
    150 
    151 } // end llvm namespace
    152 
    153 
    154 #endif
    155