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