LCOV - code coverage report
Current view: top level - toolbox - OStream.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 3 0.0 %
Date: 2015-06-10 18:10:59 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /* src/toolbox/OStream.hpp - simple output stream
       2             : 
       3             :    Copyright (C) 1996-2013
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             : 
       6             :    This file is part of CACAO.
       7             : 
       8             :    This program is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU General Public License as
      10             :    published by the Free Software Foundation; either version 2, or (at
      11             :    your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful, but
      14             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program; if not, write to the Free Software
      20             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      21             :    02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #ifndef OSTREAM_HPP_
      26             : #define OSTREAM_HPP_ 1
      27             : 
      28             : #include <cstdio>
      29             : 
      30             : namespace cacao {
      31             : 
      32             : class OStream;
      33             : 
      34             : OStream& out();
      35             : OStream& err();
      36             : 
      37             : class SetWidth;
      38             : class SetZero;
      39             : class SetPrecision;
      40             : class SetIndent;
      41             : class SetPrefix;
      42             : 
      43             : class FillZero;
      44             : 
      45             : class Left;
      46             : class Right;
      47             : class Dec;
      48             : class Oct;
      49             : class Hex;
      50             : class FloatDec;
      51             : class Scientific;
      52             : class FloatHex;
      53             : class Indent;
      54             : class Dedent;
      55             : class Nl;
      56             : class Flush;
      57             : 
      58             : class ThreadId;
      59             : 
      60             : // ANSI terminal control
      61             : 
      62             : enum Color {
      63             :         InvalidColor = 0,
      64             :         Black,
      65             :         Red,
      66             :         Green,
      67             :         Yellow,
      68             :         Blue,
      69             :         Magenta,
      70             :         Cyan,
      71             :         White,
      72             :         BoldBlack,
      73             :         BoldRed,
      74             :         BoldGreen,
      75             :         BoldYellow,
      76             :         BoldBlue,
      77             :         BoldMagenta,
      78             :         BoldCyan,
      79             :         BoldWhite
      80             : };
      81             : 
      82             : class ResetColor  {};
      83             : class Bold        {};
      84             : class NoBold      {};
      85             : class Underline   {};
      86             : class NoUnderline {};
      87             : 
      88             : /** Simple stream class for formatted output
      89             :  *
      90             :  * This class is designed for debugging, thus usability trumps performance.
      91             :  * It mostly mimics the iostreams library, but requires no global constructors.
      92             :  * Interally everything is forwarded to stdio
      93             :  *
      94             :  * A stream can contain a prefix or intentions.
      95             :  * The stream does not detect if your output contains a '\n' (newline) character.
      96             :  * You must use the manipulator #nl instead. It works like std::endl but
      97             :  * does not flush the stream.
      98             :  *
      99             :  * Simple examples :
     100             :  *   @code
     101             :  *      OStream os(stdout);
     102             :  *
     103             :  *      os << "Hi there, my name is " << bold << "cacao" << nobold             << nl;
     104             :  *      os << "I was born in " << 1996                                         << nl;
     105             :  *      os << "Test failures are " << underline << red << "BAD" << reset_color << nl;
     106             :  *      os                                                                     << nl;
     107             :  *      os << "Do you like hex? "       << hex       << 255  << dec            << nl;
     108             :  *      os << "Or floating point hex? " << float_hex << 17.3 << float_dec      << nl;
     109             :  *   @endcode
     110             :  *
     111             :  * Unlike a std::iostream you can copy construct an OStream.
     112             :  * A copied OStream will write to the same file but has it's own set of
     113             :  * format flags that you can set independent of the original stream.
     114             :  * But Colors, bold and underline are shared by all streams for a file,
     115             :  * because they are stored in the underlying terminal.
     116             :  *  You should not write nl to the copied stream since the original will not
     117             :  * detect the newline.
     118             :  *
     119             :  * Example:
     120             :  *  @code
     121             :  *      struct MyLittlePony {
     122             :  *              const char *name;
     123             :  *         Color       color;
     124             :  *      };
     125             :  *
     126             :  *      OStream& operator<<(OStream& os, const MyLittlePony& mlp) {
     127             :  *              OStream os2 = os; // new stream with new flags
     128             :  *
     129             :  *              os2 << mlp.color;
     130             :  *              os2 << "My little pony is called " << setw(20) << right << mlp.name;
     131             :  *              os2 << hex;
     132             :  *
     133             :  *              // Forgot to unset hex for os2: no problem, hex flag is not shared
     134             :  *              // Forgot to unset color: big problem, colors are shared!
     135             :  *
     136             :  *              return os; // always return original stream
     137             :  *      }
     138             :  *  @endcode
     139             :  */
     140             : class OStream {
     141             : public:
     142             :         /// create a new stream with default flags
     143             :         OStream(FILE *file);
     144             : 
     145             :         /** copy stream
     146             :          *
     147             :          * creates a new stream with the same file
     148             :          * but default
     149             :          */
     150             :         OStream(const OStream&);
     151             : 
     152             :         OStream& operator<<(char);
     153             :         OStream& operator<<(bool);
     154             :         OStream& operator<<(long);
     155             :         OStream& operator<<(unsigned long);
     156             :         OStream& operator<<(long long );
     157             :         OStream& operator<<(unsigned long long);
     158             :         OStream& operator<<(double);
     159             :         OStream& operator<<(const void*);
     160             :         OStream& operator<<(const char*);
     161             : 
     162             :         OStream& operator<<(unsigned int n) {
     163             :                 return this->operator<<(static_cast<unsigned long>(n));
     164             :         }
     165             : 
     166             :         OStream& operator<<(int n) {
     167             :                 return this->operator<<(static_cast<long>(n));
     168             :         }
     169             : 
     170             :         // manipulators
     171             :         OStream& operator<<(const SetWidth&);
     172             :         OStream& operator<<(const SetZero&);
     173             :         OStream& operator<<(const SetPrecision&);
     174             :         OStream& operator<<(const SetIndent&);
     175             :         OStream& operator<<(const SetPrefix&);
     176             : 
     177             :         OStream& operator<<(const FillZero&);
     178             : 
     179             :         OStream& operator<<(const Left&);
     180             :         OStream& operator<<(const Right&);
     181             : 
     182             :         OStream& operator<<(const Dec&);
     183             :         OStream& operator<<(const Oct&);
     184             :         OStream& operator<<(const Hex&);
     185             : 
     186             :         OStream& operator<<(const FloatDec&);
     187             :         OStream& operator<<(const Scientific&);
     188             :         OStream& operator<<(const FloatHex&);
     189             : 
     190             :         OStream& operator<<(const Indent&);
     191             :         OStream& operator<<(const Dedent&);
     192             : 
     193             :         OStream& operator<<(const Nl&);
     194             :         OStream& operator<<(const Flush&);
     195             : 
     196             :         OStream& operator<<(const ThreadId&);
     197             : 
     198             :         // ANSI codes
     199             :         OStream& operator<<(Color);
     200             : 
     201             :         OStream& operator<<(const ResetColor&);
     202             : 
     203             :         OStream& operator<<(const Bold&);
     204             :         OStream& operator<<(const NoBold&);
     205             :         OStream& operator<<(const Underline&);
     206             :         OStream& operator<<(const NoUnderline&);
     207             : 
     208             :         void set_file(FILE *file) { this->file = file; }
     209             : private:
     210             :         void on_newline();
     211             : 
     212             :         /// initialize all format flags to their default value
     213             :         void init_flag_defaults();
     214             : 
     215             :         /// initialize all flags that only apply to one write operation
     216             :         void init_transient_flags();
     217             :         /// initialize all flags that survive a write operation
     218             :         void init_persistent_flags();
     219             : 
     220             :         /// file stream writes to
     221             :         FILE  *file;
     222             : 
     223             :         /// true iff we are at the beginning of a new line
     224             :         bool newline;
     225             : 
     226             :         /// supports ansi escape codes
     227             :         bool use_color;
     228             : 
     229             :         enum IntegerFormat {
     230             :                 IntFmt_decimal,
     231             :                 IntFmt_octal,
     232             :                 IntFmt_hexadecimal
     233             :         };
     234             :         enum FloatFormat {
     235             :                 FloatFmt_decimal,
     236             :                 FloatFmt_scientific,
     237             :                 FloatFmt_hexadecimal
     238             :         };
     239             : 
     240             :         // ********** format flags
     241             : 
     242             :         /** padding for next write
     243             :          *
     244             :          * ! width is reset to zero by all standard write operations !
     245             :          *
     246             :          * default value is 0
     247             :          */
     248             :         size_t width;
     249             : 
     250             :         /** precision
     251             :          *
     252             :          * ! precision is reset to -1 by all standard write operations !
     253             :          *
     254             :          * default value is -1 (i.e. turned off)
     255             :          */
     256             :         int precision;
     257             : 
     258             :         /** fill_zero
     259             :          *
     260             :          * ! fill_zero is reset to false by all standard write operations !
     261             :          *
     262             :          * default value is false
     263             :          */
     264             :         bool fill_zero;
     265             : 
     266             :         /** Alignment to use when padding text
     267             :          *
     268             :          * default value is OStream::Align_right
     269             :          */
     270             :         enum {
     271             :                 Align_left,
     272             :                 Align_right
     273             :         } align;
     274             : 
     275             :         /** format used to print integer types
     276             :          *
     277             :          * default value is \link OStream::IntegerFormat::IntFmt_decimal decimal \endlink
     278             :          */
     279             :         IntegerFormat int_fmt;
     280             : 
     281             :         /** format used to print floating point types
     282             :          *
     283             :          * default value is \link OStream::FloatFormat::FloatFmt_decimal decimal \endlink
     284             :          */
     285             :         FloatFormat float_fmt;
     286             : 
     287             :         /** indentation level
     288             :          *
     289             :          * every new line will start with OStream::Flags::indent_lvl * 4 spaces
     290             :          *
     291             :          * default value is 0
     292             :          */
     293             :         size_t indent_lvl;
     294             : 
     295             :         /** line prefix
     296             :          *
     297             :          * ignored if NULL
     298             :          * will be printed at start of every new line
     299             :          *
     300             :          * default value is NULL
     301             :          */
     302             :         const char *prefix;
     303             : 
     304             :         /** color line prefix is printed in
     305             :          *
     306             :          * ignored if negative
     307             :          *
     308             :          * default value is -1
     309             :          */
     310             :         Color prefix_color;
     311             : 
     312             :         friend class Logging;
     313             : };
     314             : 
     315             : /// Set width flag for next item to be written.
     316             : class SetWidth {
     317             :         size_t width;
     318             : public:
     319           0 :         SetWidth(size_t width) : width(width) {}
     320             : 
     321             : friend class OStream;
     322             : };
     323             : 
     324             : /// Set width flag and fill zero for next item to be written.
     325             : class SetZero {
     326             :         size_t width;
     327             : public:
     328             :         SetZero(size_t width) : width(width) {}
     329             : 
     330             : friend class OStream;
     331             : };
     332             : 
     333             : /// Set precision flag for next item to be written.
     334             : class SetPrecision {
     335             :         int precision;
     336             : public:
     337             :         SetPrecision(int precision) : precision(precision) {}
     338             : 
     339             : friend class OStream;
     340             : };
     341             : 
     342             : /// Set indent level in stream
     343             : class SetIndent {
     344             :         size_t indent;
     345             : public:
     346             :         SetIndent(size_t indent) : indent(indent) {}
     347             : 
     348             : friend class OStream;
     349             : };
     350             : 
     351             : /// Set stream prefix
     352             : class SetPrefix {
     353             :         const char *prefix;
     354             :         Color       color;
     355             : public:
     356             :         SetPrefix(const char *prefix, Color color)
     357             :          : prefix(prefix), color(color) {}
     358             : 
     359             : friend class OStream;
     360             : };
     361             : 
     362             : class FillZero   {};
     363             : 
     364             : class Left       {};
     365             : class Right      {};
     366             : class Dec        {};
     367             : class Oct        {};
     368             : class Hex        {};
     369             : class FloatDec   {};
     370             : class Scientific {};
     371             : class FloatHex   {};
     372             : class Indent     {};
     373             : class Dedent     {};
     374             : class Nl         {};
     375             : class Flush      {};
     376             : 
     377             : class ThreadId {};
     378             : 
     379             : class ResetColor;
     380             : class Bold;
     381             : class NoBold;
     382             : class Underline;
     383             : class NoUnderline;
     384             : 
     385           0 : inline static SetWidth setw(size_t w) {
     386           0 :         return SetWidth(w);
     387             : }
     388             : inline static SetZero setz(size_t w) {
     389             :         return SetZero(w);
     390             : }
     391             : inline static SetPrecision setprecision(int p) {
     392             :         return SetPrecision(p);
     393             : }
     394             : inline static SetIndent setindent(size_t i) {
     395             :         return SetIndent(i);
     396             : }
     397             : inline static SetPrefix setprefix(const char *prefix, Color color) {
     398             :         return SetPrefix(prefix, color);
     399             : }
     400             : 
     401             : extern FillZero   fillzero;
     402             : extern Left       left;
     403             : extern Right      right;
     404             : extern Dec        dec;
     405             : extern Oct        oct;
     406             : extern Hex        hex;
     407             : extern FloatDec   float_dec;
     408             : extern Scientific scientific;
     409             : extern FloatHex   float_hex;
     410             : extern Indent     indent;
     411             : extern Dedent     dedent;
     412             : extern Nl         nl;
     413             : extern Flush      flush;
     414             : 
     415             : // pipe this into a stream to print the current thread's id
     416             : extern ThreadId threadid;
     417             : 
     418             : extern ResetColor  reset_color;
     419             : extern Bold        bold;
     420             : extern NoBold      nobold;
     421             : extern Underline   underline;
     422             : extern NoUnderline nounderline;
     423             : 
     424             : // helper templates
     425             : template <class _ForwardIterator>
     426             : inline OStream& print_container(OStream &OS, _ForwardIterator i, const _ForwardIterator &e) {
     427             :         if (i == e)
     428             :                 return OS << "[<empty>]";
     429             :         OS << "[" << *i;
     430             :         ++i;
     431             :         for( ; i != e ; ++i) {
     432             :                 OS << ", " << *i;
     433             :         }
     434             :         return OS << "]";
     435             : }
     436             : 
     437             : } // end namespace cacao
     438             : 
     439             : #endif // OSTREAM_HPP_
     440             : 
     441             : 
     442             : /*
     443             :  * These are local overrides for various environment variables in Emacs.
     444             :  * Please do not remove this and leave it at the end of the file, where
     445             :  * Emacs will automagically detect them.
     446             :  * ---------------------------------------------------------------------
     447             :  * Local variables:
     448             :  * mode: c++
     449             :  * indent-tabs-mode: t
     450             :  * c-basic-offset: 4
     451             :  * tab-width: 4
     452             :  * End:
     453             :  * vim:noexpandtab:sw=4:ts=4:
     454             :  */

Generated by: LCOV version 1.11