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;
106 void initialise_categories_mask();
111 : categories_mask(1 << DEBUGLOG_CATEGORY_API), fd(-1), indent_level(0)
118 bool is_category_wanted(debuglog_categories
category) {
122 if (category == DEBUGLOG_CATEGORY_ALWAYS)
return true;
123 if (category == DEBUGLOG_CATEGORY_NEVER)
return false;
124 if (fd == -1) initialise_categories_mask();
125 return (categories_mask >> category) & 1;
129 void log_line(debuglog_categories category,
const std::string& msg);
131 void indent() { ++indent_level; }
134 if (indent_level) --indent_level;
144 typedef enum { NO_ARGS } NoArguments_;
147 inline std::ostream &
operator<<(std::ostream &o, Xapian::NoArguments_) {
151 using Xapian::NO_ARGS;
153 extern DebugLogger xapian_debuglogger_;
157 #define LOGLINE_ALWAYS_(CATEGORY, MSG) do { \ 158 std::ostringstream xapian_debuglog_ostream_; \ 159 xapian_debuglog_ostream_ << MSG; \ 160 xapian_debuglogger_.log_line(CATEGORY, xapian_debuglog_ostream_.str()); \ 165 #define LOGLINE_(CATEGORY, MSG) do { \ 166 debuglog_categories xapian_debuglog_category_ = (CATEGORY); \ 167 if (xapian_debuglogger_.is_category_wanted(xapian_debuglog_category_)) { \ 168 LOGLINE_ALWAYS_(xapian_debuglog_category_, MSG); \ 183 const void* this_ptr;
192 int uncaught_exceptions;
194 static int get_uncaught_exceptions() {
195 #if __cplusplus >= 201703L 196 return std::uncaught_exceptions();
198 return int(std::uncaught_exception());
204 DebugLogFunc(
const void* this_ptr_, debuglog_categories category_,
205 const char* return_type,
const char* func_name,
206 const std::string& params)
207 : this_ptr(this_ptr_), category(category_),
208 uncaught_exceptions(get_uncaught_exceptions())
210 if (is_category_wanted()) {
211 func.assign(return_type);
217 LOGLINE_ALWAYS_(category,
'[' << this_ptr <<
"] " << func);
218 xapian_debuglogger_.indent();
223 void log_return_value(
const std::string& return_value) {
224 xapian_debuglogger_.outdent();
225 LOGLINE_(category,
'[' << this_ptr <<
"] " << func <<
" returned: " <<
229 category = DEBUGLOG_CATEGORY_NEVER;
233 bool is_category_wanted()
const {
234 return xapian_debuglogger_.is_category_wanted(category);
243 if (!is_category_wanted())
return;
244 xapian_debuglogger_.outdent();
245 if (get_uncaught_exceptions() > uncaught_exceptions) {
247 LOGLINE_(category,
'[' << this_ptr <<
"] " << func <<
248 " exited due to exception");
250 LOGLINE_(category,
'[' << this_ptr <<
"] " << func <<
251 " returned (not marked up for return logging)");
265 class DebugLogFuncVoid {
267 const void* this_ptr;
276 int uncaught_exceptions;
278 static int get_uncaught_exceptions() {
279 #if __cplusplus >= 201703L 280 return std::uncaught_exceptions();
282 return int(std::uncaught_exception());
288 DebugLogFuncVoid(
const void* this_ptr_, debuglog_categories category_,
289 const char* func_name,
290 const std::string& params)
291 : this_ptr(this_ptr_), category(category_),
292 uncaught_exceptions(get_uncaught_exceptions())
294 if (is_category_wanted()) {
295 func.assign(
"void ");
300 LOGLINE_ALWAYS_(category,
'[' << this_ptr <<
"] " << func);
301 xapian_debuglogger_.indent();
306 DebugLogFuncVoid(
const void* this_ptr_, debuglog_categories category_,
307 const std::string& params,
308 const char* class_name)
309 : this_ptr(this_ptr_), category(category_),
310 uncaught_exceptions(get_uncaught_exceptions())
312 if (is_category_wanted()) {
313 func.assign(class_name);
317 const char* ctor_name = std::strrchr(class_name,
':');
321 ctor_name = class_name;
326 LOGLINE_ALWAYS_(category,
'[' << this_ptr <<
"] " << func);
327 xapian_debuglogger_.indent();
332 DebugLogFuncVoid(
const void* this_ptr_, debuglog_categories category_,
333 const char* class_name)
334 : this_ptr(this_ptr_), category(category_),
335 uncaught_exceptions(get_uncaught_exceptions())
337 if (is_category_wanted()) {
338 func.assign(class_name);
341 const char* dtor_name = std::strrchr(class_name,
':');
345 dtor_name = class_name;
348 LOGLINE_(category,
'[' << this_ptr <<
"] " << func);
349 xapian_debuglogger_.indent();
354 bool is_category_wanted()
const {
355 return xapian_debuglogger_.is_category_wanted(category);
363 ~DebugLogFuncVoid() {
364 if (!is_category_wanted())
return;
365 xapian_debuglogger_.outdent();
367 if (get_uncaught_exceptions() > uncaught_exceptions) {
369 reason =
" exited due to exception";
371 reason =
" returned";
373 LOGLINE_ALWAYS_(category,
'[' << this_ptr <<
"] " << func << reason);
379 # define XAPIAN_UNUSED __attribute__((unused)) 381 # define XAPIAN_UNUSED 385 #define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS) \ 386 typedef TYPE xapian_logcall_return_type_ XAPIAN_UNUSED; \ 387 std::string xapian_logcall_parameters_; \ 388 if (xapian_debuglogger_.is_category_wanted(DEBUGLOG_CATEGORY_##CATEGORY)) { \ 389 std::ostringstream xapian_logcall_ostream_; \ 390 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \ 391 xapian_logcall_stream_ << PARAMS; \ 392 xapian_logcall_parameters_ = xapian_logcall_ostream_.str(); \ 394 DebugLogFunc xapian_logcall_(static_cast<const void*>(this), \ 395 DEBUGLOG_CATEGORY_##CATEGORY, #TYPE, FUNC, \ 396 xapian_logcall_parameters_) 399 #define LOGCALL_VOID(CATEGORY, FUNC, PARAMS) \ 400 std::string xapian_logcall_parameters_; \ 401 if (xapian_debuglogger_.is_category_wanted(DEBUGLOG_CATEGORY_##CATEGORY)) { \ 402 std::ostringstream xapian_logcall_ostream_; \ 403 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \ 404 xapian_logcall_stream_ << PARAMS; \ 405 xapian_logcall_parameters_ = xapian_logcall_ostream_.str(); \ 407 DebugLogFuncVoid xapian_logcall_(static_cast<const void*>(this), \ 408 DEBUGLOG_CATEGORY_##CATEGORY, FUNC, \ 409 xapian_logcall_parameters_) 412 #define LOGCALL_CTOR(CATEGORY, CLASS, PARAMS) \ 413 std::string xapian_logcall_parameters_; \ 414 if (xapian_debuglogger_.is_category_wanted(DEBUGLOG_CATEGORY_##CATEGORY)) { \ 415 std::ostringstream xapian_logcall_ostream_; \ 416 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \ 417 xapian_logcall_stream_ << PARAMS; \ 418 xapian_logcall_parameters_ = xapian_logcall_ostream_.str(); \ 420 DebugLogFuncVoid xapian_logcall_(static_cast<const void*>(this), \ 421 DEBUGLOG_CATEGORY_##CATEGORY, \ 422 xapian_logcall_parameters_, CLASS) 425 #define LOGCALL_DTOR(CATEGORY, CLASS) \ 426 DebugLogFuncVoid xapian_logcall_(static_cast<const void*>(this), \ 427 DEBUGLOG_CATEGORY_##CATEGORY, CLASS) 430 #define LOGCALL_STATIC(CATEGORY, TYPE, FUNC, PARAMS) \ 431 typedef TYPE xapian_logcall_return_type_ XAPIAN_UNUSED; \ 432 std::string xapian_logcall_parameters_; \ 433 if (xapian_debuglogger_.is_category_wanted(DEBUGLOG_CATEGORY_##CATEGORY)) { \ 434 std::ostringstream xapian_logcall_ostream_; \ 435 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \ 436 xapian_logcall_stream_ << PARAMS; \ 437 xapian_logcall_parameters_ = xapian_logcall_ostream_.str(); \ 439 DebugLogFunc xapian_logcall_(0, DEBUGLOG_CATEGORY_##CATEGORY, #TYPE, FUNC, xapian_logcall_parameters_) 442 #define LOGCALL_STATIC_VOID(CATEGORY, FUNC, PARAMS) \ 443 std::string xapian_logcall_parameters_; \ 444 if (xapian_debuglogger_.is_category_wanted(DEBUGLOG_CATEGORY_##CATEGORY)) { \ 445 std::ostringstream xapian_logcall_ostream_; \ 446 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \ 447 xapian_logcall_stream_ << PARAMS; \ 448 xapian_logcall_parameters_ = xapian_logcall_ostream_.str(); \ 450 DebugLogFuncVoid xapian_logcall_(0, DEBUGLOG_CATEGORY_##CATEGORY, FUNC, xapian_logcall_parameters_) 453 #define RETURN(A) do { \ 454 xapian_logcall_return_type_ xapian_logcall_return_ = A; \ 455 if (xapian_logcall_.is_category_wanted()) { \ 456 std::ostringstream xapian_logcall_ostream_; \ 457 PrettyOStream<std::ostringstream> xapian_logcall_stream_(xapian_logcall_ostream_); \ 458 xapian_logcall_stream_ << xapian_logcall_return_; \ 459 xapian_logcall_.log_return_value(xapian_logcall_ostream_.str()); \ 461 return xapian_logcall_return_; \ 469 #define LOGLINE(a,b) LOGLINE_(DEBUGLOG_CATEGORY_##a, b) 472 #define LOGVALUE(a,b) LOGLINE_(DEBUGLOG_CATEGORY_##a, #b" = " << b) 483 #define RETURN_TYPE(...) __VA_ARGS__ 487 #define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS) (void)0 488 #define LOGCALL_VOID(CATEGORY, FUNC, PARAMS) (void)0 489 #define LOGCALL_CTOR(CATEGORY, CLASS, PARAMS) (void)0 490 #define LOGCALL_DTOR(CATEGORY, CLASS) (void)0 491 #define LOGCALL_STATIC(CATEGORY, TYPE, FUNC, PARAMS) (void)0 492 #define LOGCALL_STATIC_VOID(CATEGORY, FUNC, PARAMS) (void)0 493 #define RETURN(A) return A 494 #define LOGLINE(a,b) (void)0 495 #define LOGVALUE(a,b) (void)0 499 #endif // XAPIAN_INCLUDED_DEBUGLOG_H The Xapian namespace contains public interfaces for the Xapian library.
category
Each Unicode character is in exactly one of these categories.
Convert types to pretty representations.
Functions for output of strings describing internal Xapian objects.
PrettyOStream< S > & operator<<(PrettyOStream< S > &ps, const T &t)
Default is to output as std::ostream would.