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