]> git.lyx.org Git - lyx.git/blob - src/support/DebugStream.h
Some cleanups to compile with dec cxx. We are not there yet though.
[lyx.git] / src / support / DebugStream.h
1 // -*- C++ -*-
2
3 // Created by Lars Gullik Bjønnes
4 // Copyright 1999 Lars Gullik Bjønnes (larsbj@lyx.org)
5 // Released under the Gnu General Public License
6
7 // Implemented and tested on g++ 2.7.2.3
8
9 // Primarily developed for use in the LyX Project http://www.lyx.org/
10 // but should be adaptable to any project.
11
12 #ifndef DEBUGSTREAM_H
13 #define DEBUGSTREAM_H
14
15 #ifdef _STANDARD_C_PLUS_PLUS
16 #define MODERN_STL
17 #endif
18
19 #ifdef MODERN_STL
20 #include <ostream>
21 #else
22 #include <iostream>
23 #endif
24
25 #ifdef MODERN_STL
26 using std::ostream;
27 using std::streambuf;
28 using std::streamsize;
29 using std::filebuf;
30 using std::cerr;
31 using std::ios;
32 using std::endl; 
33 #endif
34
35 #ifdef TEST_DEBUGSTREAM
36 #include <string>
37 struct Debug {
38         ///
39         enum type {
40                 ///
41                 NONE = 0,
42                 ///
43                 INFO       = (1 << 0),   // 1
44                 ///
45                 WARN       = (1 << 1),   // 2
46                 ///
47                 CRIT       = (1 << 2)   // 4
48         };
49         ///
50         static const type ANY = type(INFO | WARN | CRIT);
51
52         /** A function to convert symbolic string names on debug levels
53             to their numerical value.
54         */
55         static Debug::type value(std::string const & val) {
56                 if (val == "NONE") return Debug::NONE;
57                 if (val == "INFO") return Debug::INFO;
58                 if (val == "WARN") return Debug::WARN;
59                 if (val == "CRIT") return Debug::CRIT;
60                 return Debug::NONE;
61         }
62
63 };
64 #endif
65
66 /** DebugStream is a ostream intended for debug output. It has also support
67     for a logfile. Debug output is output to cerr and if the logfile is set,
68     to the logfile.
69
70     Example of Usage:
71     DebugStream debug;
72     debug.level(Debug::INFO);
73     debug.debug(Debug::WARN) << "WARN\n";
74     debug[Debug::INFO] << "INFO\n";
75     debug << "Always\n";
76
77     Will output:
78     INFO
79     Always
80
81     If you want to have debug output from time critical code you should 
82     use this construct:
83     if (debug.debugging(Debug::INFO)) {
84          debug << "...debug output...\n";
85     }
86     
87     To give debug info even if no debug (NONE) is requested:
88     debug << "... always output ...\n";
89
90     To give debug output regardless of what debug level is set (!NONE):
91     debug.debug() << "...on debug output...\n";
92     debug[Debug::ANY] << "...on debug output...\n";
93
94     To give debug output when a specific debug level is set (INFO):
95     debug.debug(Debug::INFO) << "...info...\n";
96     debug[Debug::INFO] << "...info...\n";
97
98     To give debug output when either on of debug levels is set (INFO or CRIT):
99     debug.debug(Debug::type(Debug::INFO | Debug::CRIT)) << "...info/crit...\n";
100     debug[Debug::type(Debug::INFO | Debug::CRIT)] << "...info/crit...\n";
101
102 */
103 class DebugStream : public ostream {
104 public:
105         /// Constructor, sets the debug level to t.
106         DebugStream(Debug::type t = Debug::NONE);
107         
108         /// Constructor, sets the log file to f, and the debug level to t.
109         DebugStream(char const * f, Debug::type t = Debug::NONE);
110
111         ///
112         virtual ~DebugStream();
113         
114         /// Sets the debug level to t.
115         void level(Debug::type t) {
116                 dt = Debug::type(t & Debug::ANY);
117         }
118
119         /// Returns the current debug level.
120         Debug::type level() const {
121                 return dt;
122         }
123
124         /// Adds t to the current debug level.
125         void addLevel(Debug::type t) {
126                 dt = Debug::type(dt | t);
127         }
128
129         /// Deletes t from the current debug level.
130         void delLevel(Debug::type t) {
131                 dt = Debug::type(dt & ~t);
132         }
133
134         /// Sets the debugstreams' logfile to f.
135         void logFile(char const * f);
136         
137         /// Returns true if t is part of the current debug level.
138         bool debugging(Debug::type t = Debug::ANY) const
139         {
140                 if (dt & t) return true;
141                 return false;
142         }
143
144         
145         /** Returns the no-op stream if t is not part of the
146             current debug level otherwise the real debug stream
147             is used.
148         */
149         ostream & debug(Debug::type t = Debug::ANY) {
150                 if (dt & t) return *this;
151                 return nullstream;
152         }
153
154         
155         /** This is an operator to give a more convenient use:
156             dbgstream[Debug::INFO] << "Info!\n";
157         */
158         ostream & operator[](Debug::type t) {
159                 return debug(t);
160         }
161 private:
162         /// The current debug level
163         Debug::type dt;
164         /// The no-op stream.
165         ostream nullstream;
166         struct debugstream_internal;
167         debugstream_internal * internal;
168 };
169
170 #endif