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