21 #ifndef XAPIAN_INCLUDED_DEBUGLOG_H
22 #define XAPIAN_INCLUDED_DEBUGLOG_H
27 #ifdef XAPIAN_REALLY_NO_DEBUG_LOG
28 # ifdef XAPIAN_DEBUG_LOG
29 # undef XAPIAN_DEBUG_LOG
33 #ifdef XAPIAN_DEBUG_LOG
44 enum debuglog_categories {
46 DEBUGLOG_CATEGORY_NEVER = 0,
49 DEBUGLOG_CATEGORY_API = (
'A' -
'@'),
52 DEBUGLOG_CATEGORY_DB = (
'D' -
'@'),
55 DEBUGLOG_CATEGORY_EXCEPTION = (
'X' -
'@'),
58 DEBUGLOG_CATEGORY_EXPAND = (
'E' -
'@'),
61 DEBUGLOG_CATEGORY_MATCH = (
'M' -
'@'),
64 DEBUGLOG_CATEGORY_QUERYPARSER = (
'Q' -
'@'),
67 DEBUGLOG_CATEGORY_REMOTE = (
'R' -
'@'),
70 DEBUGLOG_CATEGORY_REPLICA = (
'C' -
'@'),
73 DEBUGLOG_CATEGORY_SPELLING = (
'S' -
'@'),
76 DEBUGLOG_CATEGORY_UNKNOWN = (
'U' -
'@'),
79 DEBUGLOG_CATEGORY_WTCALC = (
'W' -
'@'),
82 DEBUGLOG_CATEGORY_QUERY = (
'Y' -
'@'),
85 DEBUGLOG_CATEGORY_ALWAYS = 31
91 void operator=(
const DebugLogger&);
94 DebugLogger(
const DebugLogger&);
97 unsigned int categories_mask = 1 << DEBUGLOG_CATEGORY_API;
103 int indent_level = 0;
106 void initialise_categories_mask();
116 bool is_category_wanted(debuglog_categories
category) {
120 if (
category == DEBUGLOG_CATEGORY_ALWAYS)
return true;
121 if (
category == DEBUGLOG_CATEGORY_NEVER)
return false;
122 if (fd == -1) initialise_categories_mask();
123 return (categories_mask >>
category) & 1;
127 void log_line(debuglog_categories
category,
const std::string& msg);
129 void indent() { ++indent_level; }
132 if (indent_level) --indent_level;
142 typedef enum { NO_ARGS } NoArguments_;
145 inline std::ostream &
operator<<(std::ostream &o, Xapian::NoArguments_) {
149 using Xapian::NO_ARGS;
151 extern DebugLogger xapian_debuglogger_;
155 #define LOGLINE_ALWAYS_(CATEGORY, MSG) do { \
156 std::ostringstream xapian_debuglog_ostream_; \
157 xapian_debuglog_ostream_ << MSG; \
158 xapian_debuglogger_.log_line(CATEGORY, xapian_debuglog_ostream_.str()); \
163 #define LOGLINE_(CATEGORY, MSG) do { \
164 debuglog_categories xapian_debuglog_category_ = (CATEGORY); \
165 if (xapian_debuglogger_.is_category_wanted(xapian_debuglog_category_)) { \
166 LOGLINE_ALWAYS_(xapian_debuglog_category_, MSG); \
181 const void* this_ptr;
190 int uncaught_exceptions;
192 static int get_uncaught_exceptions() {
193 return std::uncaught_exceptions();
198 DebugLogFunc(
const void* this_ptr_, debuglog_categories category_,
199 const char* return_type,
const char* func_name,
200 const std::string& params)
201 : this_ptr(this_ptr_),
category(category_),
202 uncaught_exceptions(get_uncaught_exceptions())
204 if (is_category_wanted()) {
205 func.assign(return_type);
211 LOGLINE_ALWAYS_(
category,
'[' << this_ptr <<
"] " << func);
212 xapian_debuglogger_.indent();
217 void log_return_value(
const std::string& return_value) {
218 xapian_debuglogger_.outdent();
219 LOGLINE_(
category,
'[' << this_ptr <<
"] " << func <<
" returned: " <<
227 bool is_category_wanted()
const {
228 return xapian_debuglogger_.is_category_wanted(
category);
237 if (!is_category_wanted())
return;
238 xapian_debuglogger_.outdent();
239 if (get_uncaught_exceptions() > uncaught_exceptions) {
241 LOGLINE_(
category,
'[' << this_ptr <<
"] " << func <<
242 " exited due to exception");
244 LOGLINE_(
category,
'[' << this_ptr <<
"] " << func <<
245 " returned (not marked up for return logging)");
259 class DebugLogFuncVoid {
261 const void* this_ptr;
270 int uncaught_exceptions;
272 static int get_uncaught_exceptions() {
273 return std::uncaught_exceptions();
278 DebugLogFuncVoid(
const void* this_ptr_, debuglog_categories category_,
279 const char* func_name,
280 const std::string& params)
281 : this_ptr(this_ptr_),
category(category_),
282 uncaught_exceptions(get_uncaught_exceptions())
284 if (is_category_wanted()) {
285 func.assign(
"void ");
290 LOGLINE_ALWAYS_(
category,
'[' << this_ptr <<
"] " << func);
291 xapian_debuglogger_.indent();
296 DebugLogFuncVoid(
const void* this_ptr_, debuglog_categories category_,
297 const std::string& params,
298 const char* class_name)
299 : this_ptr(this_ptr_),
category(category_),
300 uncaught_exceptions(get_uncaught_exceptions())
302 if (is_category_wanted()) {
303 func.assign(class_name);
307 const char* ctor_name = std::strrchr(class_name,
':');
311 ctor_name = class_name;
316 LOGLINE_ALWAYS_(
category,
'[' << this_ptr <<
"] " << func);
317 xapian_debuglogger_.indent();
322 DebugLogFuncVoid(
const void* this_ptr_, debuglog_categories category_,
323 const char* class_name)
324 : this_ptr(this_ptr_),
category(category_),
325 uncaught_exceptions(get_uncaught_exceptions())
327 if (is_category_wanted()) {
328 func.assign(class_name);
331 const char* dtor_name = std::strrchr(class_name,
':');
335 dtor_name = class_name;
338 LOGLINE_(
category,
'[' << this_ptr <<
"] " << func);
339 xapian_debuglogger_.indent();
344 bool is_category_wanted()
const {
345 return xapian_debuglogger_.is_category_wanted(
category);
353 ~DebugLogFuncVoid() {
354 if (!is_category_wanted())
return;
355 xapian_debuglogger_.outdent();
357 if (get_uncaught_exceptions() > uncaught_exceptions) {
359 reason =
" exited due to exception";
361 reason =
" returned";
363 LOGLINE_ALWAYS_(
category,
'[' << this_ptr <<
"] " << func << reason);
369 # define XAPIAN_UNUSED __attribute__((unused))
371 # define XAPIAN_UNUSED
375 #define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS) \
376 typedef TYPE xapian_logcall_return_type_ XAPIAN_UNUSED; \
377 std::string xapian_logcall_parameters_; \
378 if (xapian_debuglogger_.is_category_wanted(DEBUGLOG_CATEGORY_##CATEGORY)) { \
379 std::ostringstream xapian_logcall_ostream_; \
380 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \
381 xapian_logcall_stream_ << PARAMS; \
382 xapian_logcall_parameters_ = xapian_logcall_ostream_.str(); \
384 DebugLogFunc xapian_logcall_(static_cast<const void*>(this), \
385 DEBUGLOG_CATEGORY_##CATEGORY, #TYPE, FUNC, \
386 xapian_logcall_parameters_)
389 #define LOGCALL_VOID(CATEGORY, FUNC, PARAMS) \
390 std::string xapian_logcall_parameters_; \
391 if (xapian_debuglogger_.is_category_wanted(DEBUGLOG_CATEGORY_##CATEGORY)) { \
392 std::ostringstream xapian_logcall_ostream_; \
393 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \
394 xapian_logcall_stream_ << PARAMS; \
395 xapian_logcall_parameters_ = xapian_logcall_ostream_.str(); \
397 DebugLogFuncVoid xapian_logcall_(static_cast<const void*>(this), \
398 DEBUGLOG_CATEGORY_##CATEGORY, FUNC, \
399 xapian_logcall_parameters_)
402 #define LOGCALL_CTOR(CATEGORY, CLASS, PARAMS) \
403 std::string xapian_logcall_parameters_; \
404 if (xapian_debuglogger_.is_category_wanted(DEBUGLOG_CATEGORY_##CATEGORY)) { \
405 std::ostringstream xapian_logcall_ostream_; \
406 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \
407 xapian_logcall_stream_ << PARAMS; \
408 xapian_logcall_parameters_ = xapian_logcall_ostream_.str(); \
410 DebugLogFuncVoid xapian_logcall_(static_cast<const void*>(this), \
411 DEBUGLOG_CATEGORY_##CATEGORY, \
412 xapian_logcall_parameters_, CLASS)
415 #define LOGCALL_DTOR(CATEGORY, CLASS) \
416 DebugLogFuncVoid xapian_logcall_(static_cast<const void*>(this), \
417 DEBUGLOG_CATEGORY_##CATEGORY, CLASS)
420 #define LOGCALL_STATIC(CATEGORY, TYPE, FUNC, PARAMS) \
421 typedef TYPE xapian_logcall_return_type_ XAPIAN_UNUSED; \
422 std::string xapian_logcall_parameters_; \
423 if (xapian_debuglogger_.is_category_wanted(DEBUGLOG_CATEGORY_##CATEGORY)) { \
424 std::ostringstream xapian_logcall_ostream_; \
425 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \
426 xapian_logcall_stream_ << PARAMS; \
427 xapian_logcall_parameters_ = xapian_logcall_ostream_.str(); \
429 DebugLogFunc xapian_logcall_(0, DEBUGLOG_CATEGORY_##CATEGORY, #TYPE, FUNC, xapian_logcall_parameters_)
432 #define LOGCALL_STATIC_VOID(CATEGORY, FUNC, PARAMS) \
433 std::string xapian_logcall_parameters_; \
434 if (xapian_debuglogger_.is_category_wanted(DEBUGLOG_CATEGORY_##CATEGORY)) { \
435 std::ostringstream xapian_logcall_ostream_; \
436 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \
437 xapian_logcall_stream_ << PARAMS; \
438 xapian_logcall_parameters_ = xapian_logcall_ostream_.str(); \
440 DebugLogFuncVoid xapian_logcall_(0, DEBUGLOG_CATEGORY_##CATEGORY, FUNC, xapian_logcall_parameters_)
444 #define RETURN(...) do { \
445 xapian_logcall_return_type_ xapian_logcall_return_ = __VA_ARGS__; \
446 if (xapian_logcall_.is_category_wanted()) { \
447 std::ostringstream xapian_logcall_ostream_; \
448 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \
449 xapian_logcall_stream_ << xapian_logcall_return_; \
450 xapian_logcall_.log_return_value(xapian_logcall_ostream_.str()); \
452 return xapian_logcall_return_; \
460 #define LOGLINE(a,b) LOGLINE_(DEBUGLOG_CATEGORY_##a, b)
463 #define LOGVALUE(a,b) LOGLINE_(DEBUGLOG_CATEGORY_##a, #b" = " << b)
474 #define RETURN_TYPE(...) __VA_ARGS__
478 #define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS) (void)0
479 #define LOGCALL_VOID(CATEGORY, FUNC, PARAMS) (void)0
480 #define LOGCALL_CTOR(CATEGORY, CLASS, PARAMS) (void)0
481 #define LOGCALL_DTOR(CATEGORY, CLASS) (void)0
482 #define LOGCALL_STATIC(CATEGORY, TYPE, FUNC, PARAMS) (void)0
483 #define LOGCALL_STATIC_VOID(CATEGORY, FUNC, PARAMS) (void)0
484 #define RETURN(...) return __VA_ARGS__
485 #define LOGLINE(a,b) (void)0
486 #define LOGVALUE(a,b) (void)0
category
Each Unicode character is in exactly one of these categories.
The Xapian namespace contains public interfaces for the Xapian library.
std::ostream operator<< template for Xapian objects
auto operator<<(std::ostream &os, const T &t) -> decltype(t.get_description(), os)
Convert types to pretty representations.