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

Generated by: LCOV version 1.11