]> git.lyx.org Git - lyx.git/blob - src/support/debug.h
Merge branch 'master' into features/indexmacros
[lyx.git] / src / support / debug.h
1 // -*- C++ -*-
2 /**
3  * \file debug.h
4  *
5  * This file is part of LyX, the document processor.
6  * Licence details can be found in the file COPYING.
7  *
8  * \author Lars Gullik Bjønnes
9  * \author Jean-Marc Lasgouttes
10  * \author Pavel Sanda
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14
15 #ifndef LYXDEBUG_H
16 #define LYXDEBUG_H
17
18 #include "support/strfwd.h"
19
20 // Forward definitions do not work with libc++
21 // but ios_base has already been defined in strfwd
22 // if compiling with it
23 #ifndef USE_LLVM_LIBCPP
24 namespace std {
25
26 class ios_base;
27
28 template<typename CharT, typename Traits> class basic_streambuf;
29 typedef basic_streambuf<char, char_traits<char> > streambuf;
30
31 } // namespace std
32 #endif
33
34
35 namespace lyx {
36
37 ///  This is all the different debug levels that we have.
38 namespace Debug {
39         ///
40         typedef uint64_t base_type;
41         enum Type : base_type {
42                 ///
43                 NONE = 0,
44                 ///
45                 INFO       = (1u << 0),   // 1
46                 ///
47                 INIT       = (1u << 1),   // 2
48                 ///
49                 KEY        = (1u << 2),   // 4
50                 ///
51                 GUI        = (1u << 3),   // 8
52                 ///
53                 PARSER     = (1u << 4),   // 16
54                 ///
55                 LYXRC      = (1u << 5),   // 32
56                 ///
57                 KBMAP      = (1u << 6),   // 64
58                 ///
59                 OUTFILE      = (1u << 7),   // 128
60                 ///
61                 MATHED     = (1u << 8),   // 256 // Alejandro, please use this.
62                 ///
63                 FONT       = (1u << 9),   // 512
64                 ///
65                 TCLASS     = (1u << 10),  // 1024
66                 ///
67                 LYXVC      = (1u << 11),  // 2048
68                 ///
69                 LYXSERVER  = (1u << 12),  // 4096
70                 ///
71                 UNDO       = (1u << 13),  // 8192
72                 ///
73                 ACTION     = (1u << 14),   // 16384
74                 ///
75                 LYXLEX     = (1u << 15),
76                 ///
77                 DEPEND     = (1u << 16),
78                 ///
79                 INSETS     = (1u << 17),
80                 ///
81                 FILES      = (1u << 18),
82                 ///
83                 WORKAREA   = (1u << 19),
84                 ///
85                 CLIPBOARD  = (1u << 20),
86                 ///
87                 GRAPHICS   = (1u << 21),
88                 /// change tracking
89                 CHANGES    = (1u << 22),
90                 ///
91                 EXTERNAL   = (1u << 23),
92                 ///
93                 PAINTING   = (1u << 24),
94                 ///
95                 SCROLLING  = (1u << 25),
96                 ///
97                 MACROS     = (1u << 26),
98                 ///     rtl-related
99                 RTL        = (1u << 27),
100                 ///     locale related
101                 LOCALE     = (1u << 28),
102                 ///     selection
103                 SELECTION  = (1u << 29),
104                 /// Find and Replace
105                 FIND       = (1u << 30),
106                 ///
107                 FINDVERBOSE= (1u << 31),
108                 ///
109                 DEBUG      = (1L << 32),
110                 ///
111                 ANY = 0x1ffffffff
112         };
113
114         /// Return number of levels
115         int levelCount();
116
117         /// A function to convert debug level string names numerical values
118         Type value(std::string const & val);
119
120         /// Check the validity of debug level names
121         /// \return the first bad level name
122         std::string badValue(std::string const & val);
123
124         /// A function to convert index of level to their numerical value
125         Type value(int val);
126
127         /// Return description of level
128         std::string const description(Type val);
129
130         /// Return name of level
131         std::string const name(Type val);
132
133         /// Display the tags and descriptions of the current debug level
134         void showLevel(std::ostream & os, Type level);
135
136         /// Show all the possible tags that can be used for debugging
137         void showTags(std::ostream & os);
138
139
140 } // namespace Debug
141
142
143 inline void operator|=(Debug::Type & d1, Debug::Type d2)
144 {
145         d1 = static_cast<Debug::Type>(d1 | d2);
146 }
147
148
149 class LyXErr
150 {
151 public:
152         LyXErr(): dt_(Debug::NONE), stream_(0), enabled_(true),
153                   second_stream_(0), second_enabled_(false) {}
154
155         /// Disable the stream completely
156         void disable();
157         /// Enable the stream after a possible call of disable()
158         void enable();
159
160         /// Ends output
161         void endl();
162
163         /// Returns stream
164         std::ostream & stream() { return *stream_; }
165         /// Returns stream
166         operator std::ostream &() { return *stream_; }
167         /// Sets stream
168         void setStream(std::ostream & os) { stream_ = &os; }
169         /// Is the stream enabled ?
170         bool enabled() const { return enabled_; }
171
172         /// Returns second stream
173         std::ostream & secondStream() { return *second_stream_; }
174         /// Sets second stream
175         void setSecondStream(std::ostream * os)
176                 { second_enabled_ = (second_stream_ = os); }
177         /// Is the second stream is enabled?
178         bool secondEnabled() const { return second_enabled_; }
179
180         /// Sets the debug level
181         void setLevel(Debug::Type t) { dt_ = t; }
182         /// Returns the current debug level
183         Debug::Type level() const { return dt_; }
184         /// Returns true if t is part of the current debug level
185         bool debugging(Debug::base_type t = Debug::ANY) const;
186
187         ///
188         static char const * stripName(char const *);
189
190 private:
191         /// The current debug level
192         Debug::Type dt_;
193         /// The real stream
194         std::ostream * stream_;
195         /// Is the stream enabled?
196         bool enabled_;
197         /// Next stream for output duplication
198         std::ostream * second_stream_;
199         /// Is the second stream enabled?
200         bool second_enabled_;
201 };
202
203 namespace support { class FileName; }
204
205 LyXErr & operator<<(LyXErr &, void const *);
206 LyXErr & operator<<(LyXErr &, char const *);
207 LyXErr & operator<<(LyXErr &, char);
208 LyXErr & operator<<(LyXErr &, int);
209 LyXErr & operator<<(LyXErr &, unsigned int);
210 LyXErr & operator<<(LyXErr &, long);
211 LyXErr & operator<<(LyXErr &, unsigned long);
212 #ifdef HAVE_LONG_LONG_INT
213 LyXErr & operator<<(LyXErr &, long long);
214 LyXErr & operator<<(LyXErr &, unsigned long long);
215 #endif
216 LyXErr & operator<<(LyXErr &, double);
217 LyXErr & operator<<(LyXErr &, std::string const &);
218 LyXErr & operator<<(LyXErr &, docstring const &);
219 LyXErr & operator<<(LyXErr &, support::FileName const &);
220 LyXErr & operator<<(LyXErr &, std::ostream &(*)(std::ostream &));
221 LyXErr & operator<<(LyXErr &, std::ios_base &(*)(std::ios_base &));
222
223 extern LyXErr lyxerr;
224
225 } // namespace lyx
226
227 #if USE__func__
228 #       define CURRENT_POSITION __func__ ": "
229 #else
230 # define CURRENT_POSITION lyx::LyXErr::stripName(__FILE__) << " (" << __LINE__ << "): "
231 #endif
232
233 #define LYXERR(type, msg) \
234         do { \
235                 if (!lyx::lyxerr.debugging(type)) {} \
236                 else { lyx::lyxerr << CURRENT_POSITION << msg; lyx::lyxerr.endl(); } \
237         } while (0)
238
239 #define LYXERR_NOENDL(type, msg) \
240         do { \
241                 if (!lyx::lyxerr.debugging(type)) {} \
242                 else { lyx::lyxerr << CURRENT_POSITION << msg; } \
243         } while (0)
244
245 #define LYXERR_NOPOS(type, msg) \
246         do { \
247                 if (!lyx::lyxerr.debugging(type)) {} \
248                 else { lyx::lyxerr << msg; lyx::lyxerr.endl(); } \
249         } while (0)
250
251 #define LYXERR0(msg) \
252         do { \
253                 lyx::lyxerr << CURRENT_POSITION << msg; lyx::lyxerr.endl(); \
254         } while (0)
255
256
257 #endif