]> git.lyx.org Git - lyx.git/blob - src/support/DebugStream.h
the merge from branch debugstream
[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 TEST_DEBUGSTREAM
26 #include <string>
27 struct Debug {
28         ///
29         enum type {
30                 ///
31                 NONE = 0,
32                 ///
33                 INFO       = (1 << 0),   // 1
34                 ///
35                 WARN       = (1 << 1),   // 2
36                 ///
37                 CRIT       = (1 << 2)   // 4
38         };
39         ///
40         static const type ANY = type(INFO | WARN | CRIT);
41
42         /** A function to convert symbolic string names on debug levels
43             to their numerical value.
44         */
45         static Debug::type value(std::string const & val) {
46                 if (val == "NONE") return Debug::NONE;
47                 if (val == "INFO") return Debug::INFO;
48                 if (val == "WARN") return Debug::WARN;
49                 if (val == "CRIT") return Debug::CRIT;
50                 return Debug::NONE;
51         }
52
53 };
54 #endif
55
56 /** DebugStream is a ostream intended for debug output. It has also support
57     for a logfile. Debug output is output to cerr and if the logfile is set,
58     to the logfile.
59
60     Example of Usage:
61     DebugStream debug;
62     debug.level(Debug::INFO);
63     debug.debug(Debug::WARN) << "WARN\n";
64     debug[Debug::INFO] << "INFO\n";
65     debug << "Always\n";
66
67     Will output:
68     INFO
69     Always
70
71     If you want to have debug output from time critical code you should 
72     use this construct:
73     if (debug.debugging(Debug::INFO)) {
74          debug << "...debug output...\n";
75     }
76     
77     To give debug info even if no debug (NONE) is requested:
78     debug << "... always output ...\n";
79
80     To give debug output regardless of what debug level is set (!NONE):
81     debug.debug() << "...on debug output...\n";
82     debug[Debug::ANY] << "...on debug output...\n";
83
84     To give debug output when a specific debug level is set (INFO):
85     debug.debug(Debug::INFO) << "...info...\n";
86     debug[Debug::INFO] << "...info...\n";
87
88     To give debug output when either on of debug levels is set (INFO or CRIT):
89     debug.debug(Debug::type(Debug::INFO | Debug::CRIT)) << "...info/crit...\n";
90     debug[Debug::type(Debug::INFO | Debug::CRIT)] << "...info/crit...\n";
91
92 */
93 class DebugStream : public std::ostream {
94 public:
95         /// Constructor, sets the debug level to t.
96         DebugStream(Debug::type t = Debug::NONE);
97         
98         /// Constructor, sets the log file to f, and the debug level to t.
99         DebugStream(char const * f, Debug::type t = Debug::NONE);
100
101         ///
102         virtual ~DebugStream();
103         
104         /// Sets the debug level to t.
105         void level(Debug::type t) {
106                 dt = Debug::type(t & Debug::ANY);
107         }
108
109         /// Returns the current debug level.
110         Debug::type level() const {
111                 return dt;
112         }
113
114         /// Adds t to the current debug level.
115         void addLevel(Debug::type t) {
116                 dt = Debug::type(dt | t);
117         }
118
119         /// Deletes t from the current debug level.
120         void delLevel(Debug::type t) {
121                 dt = Debug::type(dt & ~t);
122         }
123
124         /// Sets the debugstreams' logfile to f.
125         void logFile(char const * f);
126         
127         /// Returns true if t is part of the current debug level.
128         bool debugging(Debug::type t = Debug::ANY) const
129         {
130                 if (dt & t) return true;
131                 return false;
132         }
133
134         
135         /** Returns the no-op stream if t is not part of the
136             current debug level otherwise the real debug stream
137             is used.
138         */
139         std::ostream & debug(Debug::type t = Debug::ANY) {
140                 if (dt & t) return *this;
141                 return nullstream;
142         }
143
144         
145         /** This is an operator to give a more convenient use:
146             dbgstream[Debug::INFO] << "Info!\n";
147         */
148         std::ostream & operator[](Debug::type t) {
149                 return debug(t);
150         }
151 private:
152         /// The current debug level
153         Debug::type dt;
154         /// The no-op stream.
155         std::ostream nullstream;
156         struct debugstream_internal;
157         debugstream_internal * internal;
158 };
159
160 #endif