1 |
|
|
// -*- mode: c++ -*- |
2 |
|
|
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse, |
3 |
|
|
// JRL, CNRS/AIST. |
4 |
|
|
// |
5 |
|
|
|
6 |
|
|
#ifndef DYNAMIC_GRAPH_DEBUG_HH |
7 |
|
|
#define DYNAMIC_GRAPH_DEBUG_HH |
8 |
|
|
#include <dynamic-graph/dynamic-graph-api.h> |
9 |
|
|
|
10 |
|
|
#include <cstdarg> |
11 |
|
|
#include <cstdio> |
12 |
|
|
#include <dynamic-graph/fwd.hh> |
13 |
|
|
#include <fstream> |
14 |
|
|
#include <sstream> |
15 |
|
|
|
16 |
|
|
#ifndef VP_DEBUG_MODE |
17 |
|
|
#define VP_DEBUG_MODE 0 |
18 |
|
|
#endif //! VP_DEBUG_MODE |
19 |
|
|
|
20 |
|
|
#ifndef VP_TEMPLATE_DEBUG_MODE |
21 |
|
|
#define VP_TEMPLATE_DEBUG_MODE 0 |
22 |
|
|
#endif //! VP_TEMPLATE_DEBUG_MODE |
23 |
|
|
|
24 |
|
|
#define DG_COMMON_TRACES \ |
25 |
|
|
do { \ |
26 |
|
|
va_list arg; \ |
27 |
|
|
va_start(arg, format); \ |
28 |
|
|
vsnprintf(charbuffer, SIZE, format, arg); \ |
29 |
|
|
va_end(arg); \ |
30 |
|
|
outputbuffer << tmpbuffer.str() << charbuffer << std::endl; \ |
31 |
|
|
} while (0) |
32 |
|
|
|
33 |
|
|
namespace dynamicgraph { |
34 |
|
|
/// \ingroup debug |
35 |
|
|
/// |
36 |
|
|
/// \brief Logging class. |
37 |
|
|
/// |
38 |
|
|
/// This class should never be used directly, please use the |
39 |
|
|
/// debugging macro instead. |
40 |
|
|
class DYNAMIC_GRAPH_DLLAPI DebugTrace { |
41 |
|
|
public: |
42 |
|
|
static const int SIZE = 512; |
43 |
|
|
|
44 |
|
|
std::stringstream tmpbuffer; |
45 |
|
|
std::ostream &outputbuffer; |
46 |
|
|
char charbuffer[SIZE + 1]; |
47 |
|
|
int traceLevel; |
48 |
|
|
int traceLevelTemplate; |
49 |
|
|
|
50 |
|
36 |
DebugTrace(std::ostream &os) : outputbuffer(os) {} |
51 |
|
|
|
52 |
|
|
inline void trace(const int level, const char *format, ...) { |
53 |
|
|
if (level <= traceLevel) DG_COMMON_TRACES; |
54 |
|
|
tmpbuffer.str(""); |
55 |
|
|
} |
56 |
|
|
|
57 |
|
|
inline void trace(const char *format, ...) { |
58 |
|
|
DG_COMMON_TRACES; |
59 |
|
|
tmpbuffer.str(""); |
60 |
|
|
} |
61 |
|
|
|
62 |
|
|
inline void trace(const int level = -1) { |
63 |
|
|
if (level <= traceLevel) { |
64 |
|
|
outputbuffer << tmpbuffer.str(); |
65 |
|
|
tmpbuffer.str(""); |
66 |
|
|
} |
67 |
|
|
} |
68 |
|
|
|
69 |
|
|
inline void traceTemplate(const int level, const char *format, ...) { |
70 |
|
|
if (level <= traceLevelTemplate) DG_COMMON_TRACES; |
71 |
|
|
tmpbuffer.str(""); |
72 |
|
|
} |
73 |
|
|
|
74 |
|
|
inline void traceTemplate(const char *format, ...) { |
75 |
|
|
DG_COMMON_TRACES; |
76 |
|
|
tmpbuffer.str(""); |
77 |
|
|
} |
78 |
|
|
|
79 |
|
|
inline DebugTrace &pre(const std::ostream &) { return *this; } |
80 |
|
|
|
81 |
|
|
inline DebugTrace &pre(const std::ostream &, int level) { |
82 |
|
|
traceLevel = level; |
83 |
|
|
return *this; |
84 |
|
|
} |
85 |
|
|
|
86 |
|
|
static const char *DEBUG_FILENAME_DEFAULT; |
87 |
|
|
static void openFile(const char *filename = DEBUG_FILENAME_DEFAULT); |
88 |
|
|
static void closeFile(const char *filename = DEBUG_FILENAME_DEFAULT); |
89 |
|
|
}; |
90 |
|
|
|
91 |
|
|
DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgDEBUGFLOW; |
92 |
|
|
DYNAMIC_GRAPH_DLLAPI extern DebugTrace dgERRORFLOW; |
93 |
|
|
} // end of namespace dynamicgraph |
94 |
|
|
|
95 |
|
|
#ifdef VP_DEBUG |
96 |
|
|
|
97 |
|
|
#define dgPREDEBUG __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :" |
98 |
|
|
#define dgPREERROR \ |
99 |
|
|
"\t!! " << __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :" |
100 |
|
|
|
101 |
|
|
#define dgDEBUG(level) \ |
102 |
|
|
if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \ |
103 |
|
|
; \ |
104 |
|
|
else \ |
105 |
|
|
dgDEBUGFLOW.outputbuffer << dgPREDEBUG |
106 |
|
|
|
107 |
|
|
#define dgDEBUGMUTE(level) \ |
108 |
|
|
if ((level > VP_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \ |
109 |
|
|
; \ |
110 |
|
|
else \ |
111 |
|
|
dgDEBUGFLOW.outputbuffer |
112 |
|
|
|
113 |
|
|
#define dgERROR \ |
114 |
|
|
if (!dgDEBUGFLOW.outputbuffer.good()) \ |
115 |
|
|
; \ |
116 |
|
|
else \ |
117 |
|
|
dgERRORFLOW.outputbuffer << dgPREERROR |
118 |
|
|
|
119 |
|
|
#define dgDEBUGF \ |
120 |
|
|
if (!dgDEBUGFLOW.outputbuffer.good()) \ |
121 |
|
|
; \ |
122 |
|
|
else \ |
123 |
|
|
dgDEBUGFLOW.pre(dgDEBUGFLOW.tmpbuffer << dgPREDEBUG, VP_DEBUG_MODE).trace |
124 |
|
|
|
125 |
|
|
#define dgERRORF \ |
126 |
|
|
if (!dgDEBUGFLOW.outputbuffer.good()) \ |
127 |
|
|
; \ |
128 |
|
|
else \ |
129 |
|
|
dgERRORFLOW.pre(dgERRORFLOW.tmpbuffer << dgPREERROR).trace |
130 |
|
|
|
131 |
|
|
// TEMPLATE |
132 |
|
|
#define dgTDEBUG(level) \ |
133 |
|
|
if ((level > VP_TEMPLATE_DEBUG_MODE) || (!dgDEBUGFLOW.outputbuffer.good())) \ |
134 |
|
|
; \ |
135 |
|
|
else \ |
136 |
|
|
dgDEBUGFLOW.outputbuffer << dgPREDEBUG |
137 |
|
|
|
138 |
|
|
#define dgTDEBUGF \ |
139 |
|
|
if (!dgDEBUGFLOW.outputbuffer.good()) \ |
140 |
|
|
; \ |
141 |
|
|
else \ |
142 |
|
|
dgDEBUGFLOW \ |
143 |
|
|
.pre(dgDEBUGFLOW.tmpbuffer << dgPREDEBUG, VP_TEMPLATE_DEBUG_MODE) \ |
144 |
|
|
.trace |
145 |
|
|
|
146 |
|
|
inline bool dgDEBUG_ENABLE(const int &level) { return level <= VP_DEBUG_MODE; } |
147 |
|
|
|
148 |
|
|
inline bool dgTDEBUG_ENABLE(const int &level) { |
149 |
|
|
return level <= VP_TEMPLATE_DEBUG_MODE; |
150 |
|
|
} |
151 |
|
|
|
152 |
|
|
#else // VP_DEBUG |
153 |
|
|
|
154 |
|
|
#define dgPREERROR \ |
155 |
|
|
"\t!! " << __FILE__ << ": " << __FUNCTION__ << "(#" << __LINE__ << ") :" |
156 |
|
|
|
157 |
|
|
#define dgDEBUG(level) \ |
158 |
|
|
if (1) \ |
159 |
|
|
; \ |
160 |
|
|
else \ |
161 |
|
|
::dynamicgraph::__null_stream() |
162 |
|
|
|
163 |
|
|
#define dgDEBUGMUTE \ |
164 |
|
|
(level) if (1); \ |
165 |
|
|
else ::dynamicgraph::__null_stream() |
166 |
|
|
|
167 |
|
|
#define dgERROR dgERRORFLOW.outputbuffer << dgPREERROR |
168 |
|
|
|
169 |
|
7 |
inline void dgDEBUGF(const int, const char *, ...) { return; } |
170 |
|
|
|
171 |
|
|
inline void dgDEBUGF(const char *, ...) { return; } |
172 |
|
|
|
173 |
|
|
inline void dgERRORF(const int, const char *, ...) { return; } |
174 |
|
|
|
175 |
|
2 |
inline void dgERRORF(const char *, ...) { return; } |
176 |
|
|
|
177 |
|
|
namespace dynamicgraph { |
178 |
|
|
inline std::ostream &__null_stream() { |
179 |
|
|
// This function should never be called. With -O3, |
180 |
|
|
// it should not appear in the generated binary. |
181 |
|
|
static std::ostream os(NULL); |
182 |
|
|
return os; |
183 |
|
|
} |
184 |
|
|
} // namespace dynamicgraph |
185 |
|
|
|
186 |
|
|
// TEMPLATE |
187 |
|
|
#define dgTDEBUG(level) \ |
188 |
|
|
if (1) \ |
189 |
|
|
; \ |
190 |
|
|
else \ |
191 |
|
|
::dynamicgraph::__null_stream() |
192 |
|
|
|
193 |
|
|
inline void dgTDEBUGF(const int, const char *, ...) { return; } |
194 |
|
|
|
195 |
|
|
inline void dgTDEBUGF(const char *, ...) { return; } |
196 |
|
|
|
197 |
|
|
#define dgDEBUG_ENABLE(level) false |
198 |
|
|
#define dgTDEBUG_ENABLE(level) false |
199 |
|
|
|
200 |
|
|
#endif //! VP_DEBUG |
201 |
|
|
|
202 |
|
|
#define dgDEBUGIN(level) dgDEBUG(level) << "# In {" << std::endl |
203 |
|
|
|
204 |
|
|
#define dgDEBUGOUT(level) dgDEBUG(level) << "# Out }" << std::endl |
205 |
|
|
|
206 |
|
|
#define dgDEBUGINOUT(level) dgDEBUG(level) << "# In/Out { }" << std::endl |
207 |
|
|
|
208 |
|
|
#define dgTDEBUGIN(level) dgTDEBUG(level) << "# In {" << std::endl |
209 |
|
|
|
210 |
|
|
#define dgTDEBUGOUT(level) dgTDEBUG(level) << "# Out }" << std::endl |
211 |
|
|
|
212 |
|
|
#define dgTDEBUGINOUT(level) dgTDEBUG(level) << "# In/Out { }" << std::endl |
213 |
|
|
|
214 |
|
|
#endif //! DYNAMIC_GRAPH_DEBUG_HH |