#ifndef DPRINT_H_INCLUDED
#define DPRINT_H_INCLUDED 1


#include "reader/support.h"

// Для обратной совместимости. Если старые проекты используют динамический логгер, продолжат его использовать.
// Новые знают, что можно влинковать его статически
// Драйвер использует свой вид логгера, так что тоже не пытаемся грузить cpsuprt.dll
#if !(defined(DBTRACE_STATIC) || (defined(_WIN32) && defined(CSP_LITE)))
#define dbtrace_print_init_ex support_print_init_ex
#define dbtrace_print_init support_print_init
#define dbtrace_print_init_ex2 support_print_init_ex2
#define dbtrace_print_init2 support_print_init2
#define dbtrace_print_done_ex support_print_done_ex
#define dbtrace_print_done support_print_done
#define dbtrace_print support_print
#define dbtrace_print_is support_print_is
#endif //!DBTRACE_STATIC && !CSP_LITE

/* Before including this file one can set something like this: */

// Способы журналирования (постфиксы к ф-циям журналировани):
// ERRO (eprint_func)
//   Unix: Sys Log (LOG_ERR)
//   Windows: Debugger Log
//   Mobile: Debugger Log
//
// NORM (dprint_func)
//   Unix: Sys Log (LOG_INFO)
//   Windows: Debugger Log
//   Mobile: Debugger Log
//
// CONS (cprint_func)
//   Unix: Console
//   Windows: Console
//   Mobile: Console
//
// ELOG (elprint_func)
//   Unix: = ERRO = Sys Log (LOG_ERR)
//   Windows: Event Log
//   Mobile: = ERRO = Debugger Log
//
// EXCL (NULL)
//   Unix: None
//   Windows: None
//   Mobile: None
//
// TODO: видно, что в текущей реализации есть недостатки:
// в отличие от Unix на Windows нет различий событий в Event Log.
// Можно удалить уровень ELOG и сделать инициализацию на Windows
// зависимой от DEBUG:
//   в Release - всё в Event Log по ERRO и NORM - с разными событиями
//   в Debug - всё в Debugger Log - как раньше
// При этом в старые реализации надо добавить параметры ELOG,
// которые будут неиспользуемыми при старом поведении.

#ifndef DB_ERROR
# if defined _DEBUG
// В Debug пишем всё в Debugger Log - там фильтровать удобней
#    if defined IOS
#      define DB_ERROR CONS
#      define DB_TRACE CONS
#      define DB_CALL CONS
#      define DB_LOG CONS
#      define DB_WARN CONS
#      define DB_DEBUG CONS
#      define DB_CRUCIAL CONS
#    else // IOS
#      define DB_ERROR ERRO
#      define DB_TRACE NORM
#      define DB_CALL NORM
#      define DB_LOG NORM
#      define DB_WARN NORM
#      define DB_DEBUG NORM
#      define DB_CRUCIAL NORM
#    endif // IOS
# else // В Release пишем почти всё в Event Log
#  if defined IOS
#      define DB_WARN CONS
#      define DB_LOG CONS
#      define DB_ERROR CONS
#      define DB_TRACE CONS
#      define DB_CALL CONS
#      define DB_DEBUG EXCL
#      define DB_CRUCIAL CONS
#  elif defined UNIX
#      define DB_WARN NORM
#      define DB_LOG NORM
#      define DB_ERROR ELOG
#      define DB_TRACE TRC
#      define DB_CALL TRC
#      define DB_DEBUG EXCL
#      define DB_CRUCIAL NORM
#  else //Windows
#      define DB_WARN ELOG
#      define DB_LOG ELOG
#      define DB_ERROR ELOG
#      define DB_TRACE TRC
#      define DB_CALL TRC
#      define DB_DEBUG EXCL
#      define DB_CRUCIAL ELOG
#  endif
# endif /* _DEBUG */
#endif

#ifdef _DEBUG
#define SUPPORT_DB_LEVEL_DEFAULT N_DB_ERROR 
#else
#define SUPPORT_DB_LEVEL_DEFAULT 0
#endif

#define SUPPORT_DBFMT_MODULE 1
#define SUPPORT_DBFMT_THREAD 2
#define SUPPORT_DBFMT_FLINE 4
#define SUPPORT_DBFMT_FUNC 8
#define SUPPORT_DBFMT_TEXT 0x10
#define SUPPORT_DBFMT_HEX 0x20
#define SUPPORT_DBFMT_ERR 0x40
#define SUPPORT_DBFMT_PID 0x80
#define SUPPORT_DBFMT_ALL 0xFF

#define SUPPORT_DBFMT_DEFAULT ((SUPPORT_DBFMT_ALL) & ~(SUPPORT_DBFMT_PID))

#define SUPPORT_DBFMT_CLEAN 0x30
#define SUPPORT_DBLEVEL_ALL 0xffffffffU

#define NCOUNT(x) x
#define CONCAT_COUNT(x,y) NCOUNT(x)##NCOUNT(y)
#define CONCAT(x,y) x##y

#define __STR2WSTR(str)	L##str
#define _STR2WSTR(str)	__STR2WSTR(str)

#if defined( _MSC_VER ) 
# if defined UNICODE
#   define SFUNC _STR2WSTR(__FUNCTION__)
# else
#   define SFUNC __FUNCTION__
# endif
#elif defined(ANDROID)
#   define SFUNC __FUNCTION__ //CPCSP-12575
#elif defined(__GNUC__)
#   define SFUNC __func__
#else /*defined( _MSC_VER ) */
#   define SFUNC __func__
#endif /*defined( _MSC_VER ) */

#define DCHAR TCHAR
#define __DTEXT(x) _TEXT(x)
#define DTEXT(x) __DTEXT(x)
#if defined _WIN32 && defined UNICODE
#   define __DFILE__ _STR2WSTR(__FILE__)
#   define D2A "%S"
#   define D2W "%s"
#else
#   define __DFILE__ __FILE__
#   define D2A "%s"
#   define D2W "%S"
#endif

//для печати TCHAR * в ASCII функции
#ifdef _UNICODE
#define _T2A "%S"
#else
#define _T2A "%s"
#endif

#if defined _WIN32
#define DBSTR(x) x
#define DBSTRA(x) x
#define DBSTRW(x) x
#else
#define DBSTR(x) (x?x:_TEXT("null"))
#define DBSTRA(x) (x?x:"null")
#define DBSTRW(x) (x?x:L"null")
#endif

#define SUPPORT_DBFTEXT_(x) x, __DFILE__, __LINE__, SFUNC
#define SUPPORT_DBFTEXTR_(x) x, DTEXT(""), __LINE__, SFUNC

#if defined _DEBUG
#define FTEXT(ctx,a) ctx,SUPPORT_DBFTEXT_(DTEXT(a))
#define FTEXT2(ctx,a,b) ctx,SUPPORT_DBFTEXT_(DTEXT(a) DTEXT(b))
#define FTEXT3(ctx,a,b,c) ctx,SUPPORT_DBFTEXT_(DTEXT(a) DTEXT(b) DTEXT(c))
#define FTEXT4(ctx,a,b,c,d) ctx,SUPPORT_DBFTEXT_(DTEXT(a) DTEXT(b) DTEXT(c) DTEXT(d))
#define FTEXT5(ctx,a,b,c,d,e) ctx,SUPPORT_DBFTEXT_(DTEXT(a) DTEXT(b) DTEXT(c) DTEXT(d) DTEXT(e))
#else
#define FTEXT(ctx,a) ctx,SUPPORT_DBFTEXTR_(DTEXT(a))
#define FTEXT2(ctx,a,b) ctx,SUPPORT_DBFTEXTR_(DTEXT(a) DTEXT(b))
#define FTEXT3(ctx,a,b,c) ctx,SUPPORT_DBFTEXTR_(DTEXT(a) DTEXT(b) DTEXT(c))
#define FTEXT4(ctx,a,b,c,d) ctx,SUPPORT_DBFTEXTR_(DTEXT(a) DTEXT(b) DTEXT(c) DTEXT(d))
#define FTEXT5(ctx,a,b,c,d,e) ctx,SUPPORT_DBFTEXTR_(DTEXT(a) DTEXT(b) DTEXT(c) DTEXT(d) DTEXT(e))
#endif

// Уровни отображения
typedef enum DBType_ {
    N_DB_ERROR = 1,
    N_DB_WARN = 2,
    N_DB_CALL = 4,
    N_DB_LOG = 8,
    N_DB_TRACE = 16,
    N_DB_DEBUG = 16,
    N_DB_CRUCIAL = 32,
    DBType_Count = 6,
    N_DB_ALL = 1 + 2 + 4 + 8 + 16 + 32
} DBType;

#define DB_PRINT_ERRO_SHIFT        (0)
#define DB_PRINT_NORM_SHIFT        (DB_PRINT_ERRO_SHIFT + DBType_Count)
#define DB_PRINT_CONS_SHIFT        (DB_PRINT_NORM_SHIFT + DBType_Count)
#define DB_PRINT_TRACE_SHIFT       (DB_PRINT_CONS_SHIFT + DBType_Count)
#define DB_PRINT_ELOG_SHIFT        (DB_PRINT_TRACE_SHIFT + DBType_Count)

#define DB_PRINT_MASK_CONSOLE(DbType) ((DbType) << DB_PRINT_CONS_SHIFT)

#define DB_PRINT_MASK(DbType) \
   (((DbType )<< DB_PRINT_ERRO_SHIFT) | \
    ((DbType) << DB_PRINT_NORM_SHIFT) | \
    ((DbType) << DB_PRINT_CONS_SHIFT) | \
    ((DbType) << DB_PRINT_ELOG_SHIFT) | \
    ((DbType) << DB_PRINT_TRACE_SHIFT))

#define DEPAREN(X) ESC(ISH X)
#define ISH(...) ISH __VA_ARGS__
#define ESC(...) ESC_(__VA_ARGS__)
#define ESC_(...) VAN ## __VA_ARGS__
#define VANISH

#define SUPPORT_DB_QPRINT_ERRO(level,param) \
    if( dbtrace_print_qis_##level param ) dbtrace_eprint_print_##level param
#define SUPPORT_DB_QPRINT_NORM(level,param) \
    if( dbtrace_print_qis_##level param ) dbtrace_dprint_print_##level param
#define SUPPORT_DB_QPRINT_CONS(level,param) \
    if( dbtrace_print_qis_##level param ) dbtrace_cprint_print_##level param
#define SUPPORT_DB_QPRINT_ELOG(level,param) \
    if( dbtrace_print_qis_##level param ) dbtrace_elprint_print_##level param
#define SUPPORT_DB_QPRINT_TRC(level,param) \
    if( dbtrace_print_qis_##level param ) dbtrace_tprint_print_##level param
#define SUPPORT_DB_QPRINT_EXCL(level,param)

#define SUPPORT_DB_QPRINT_HEX_ERRO(context,level,file,line,func,msg,buffer,length)\
    if( dbtrace_print_qis_##level(context, file) ) dbtrace_print_(context,level,msg,buffer,length,file,line,func)
#define SUPPORT_DB_QPRINT_HEX_NORM(context,level,file,line,func,msg,buffer,length)\
    if( dbtrace_print_qis_##level(context, file) ) dbtrace_print_(context,level,msg,buffer,length,file,line,func)
#define SUPPORT_DB_QPRINT_HEX_CONS(context,level,file,line,func,msg,buffer,length)\
    if( dbtrace_print_qis_##level(context, file) ) dbtrace_print_(context,level,msg,buffer,length,file,line,func)
#define SUPPORT_DB_QPRINT_HEX_ELOG(context,level,file,line,func,msg,buffer,length)\
    if( dbtrace_print_qis_##level(context, file) ) dbtrace_print_(context,level,msg,buffer,length,file,line,func)
#define SUPPORT_DB_QPRINT_HEX_TRC(context,level,file,line,func,msg,buffer,length)\
    if( dbtrace_print_qis_##level(context, file) ) dbtrace_print_(context,level,msg,buffer,length,file,line,func)
#define SUPPORT_DB_QPRINT_HEX_EXCL(context,level,file,line,func,msg,buffer,length)

#ifdef NO_DB_TRACE
#define DbTrace(level, param) 
#define DbTraceHex(level, ctx, msg, buffer, length) 
#define DbTraceInit(ctx,info,module,level,format)
#define DbTraceDone(ctx) 
#else // !NO_DB_TRACE
#define DbTrace(level, param) CONCAT(SUPPORT_DB_QPRINT_,level)(N_##level,param)  
#if defined _DEBUG
#define DbTraceHex(level, ctx, msg, buffer, length) CONCAT(SUPPORT_DB_QPRINT_HEX_,level)(ctx,N_##level,__DFILE__,__LINE__,SFUNC,msg,buffer,length)
#else
#define DbTraceHex(level, ctx, msg, buffer, length) CONCAT(SUPPORT_DB_QPRINT_HEX_,level)(ctx,N_##level,DTEXT(""),__LINE__,SFUNC,msg,buffer,length)
#endif
#define DbTraceInit(ctx,info,module,level,format) { if (ctx == NULL) ctx = dbtrace_print_init2(info,module,level,format ); }
#define DbTraceDone(ctx) { dbtrace_print_done( ctx ); ctx = NULL; }
#endif // !NO_DB_TRACE

#ifdef __cplusplus
extern "C" {
#endif
struct TSupportDbContext_;

typedef struct TSupportDbContext_ TSupportDbContext;

#ifdef SOLARIS
#define SYMBOLIC_SCOPE __symbolic
#elif defined _WIN32
#define SYMBOLIC_SCOPE  __declspec(dllexport)
#else
#define SYMBOLIC_SCOPE 
#endif // SOLARIS
extern SYMBOLIC_SCOPE TSupportDbContext* db_ctx;
#undef SYMBOLIC_SCOPE

/*!
 * \ingroup ProCPCCallbacks
 *
 * \brief Callback-функция для вывода сообщений.
 *
 * \param callback_arg [in] Параметр, переданный при регистрации callback-функции.
 *
 * \param str [in] Строка, которую нужно вывести. Не включает '\\n'.
 */
typedef void _SUPPORT_CALLBACK_CONV support_print_str_callback(void *callback_arg, const DCHAR *str);
typedef void _SUPPORT_CALLBACK_CONV support_print_str2_callback(void *callback_arg, const DCHAR *module, int level, const DCHAR *str, void *info, size_t size);
typedef void _SUPPORT_CALLBACK_CONV support_print_str_ex_callback(void *callback_arg, const DCHAR *str, size_t data_size, void *raw_data);

/*!
 * \ingroup ProCPCCallbacks
 *
 * \brief Callback-функция для получения идентификатора потока.
 *
 * \return При успешном завершении функция возвращает идентификатор потока, в противном
 * случае возвращает 0.
 */
typedef unsigned long _SUPPORT_CALLBACK_CONV support_get_thread_id_callback(void);

/* DebugInfo dprint*/
DWORD _SUPPORT_CALLBACK_CONV
dbtrace_print_init_ex(TSupportDbContext* buf, size_t * sz, void *info,
		      const DCHAR *module, unsigned level, unsigned format,
		      support_print_str_callback *dprint_str, 
		      support_print_str_callback *eprint_str,
		      support_print_str_callback *cprint_str,
		      support_print_str_callback *elprint_str,
		      support_print_str_ex_callback *dprint_str_ex, 
		      support_print_str_ex_callback *eprint_str_ex,
		      support_print_str_ex_callback *cprint_str_ex,
		      support_print_str_ex_callback *elprint_str_ex,
		      support_get_thread_id_callback *get_thread_id,
		      void *callback_arg);
TSupportDbContext* _SUPPORT_CALLBACK_CONV
dbtrace_print_init(void *info, const DCHAR *module, unsigned level,
		   unsigned format);

/* DebugInfo dprint*/
DWORD _SUPPORT_CALLBACK_CONV
dbtrace_print_init_ex2(TSupportDbContext* buf, size_t * sz, void *info,
    const DCHAR *module, unsigned level, unsigned format,
    support_print_str2_callback *dprint_str2,
    support_print_str2_callback *eprint_str2,
    support_print_str2_callback *cprint_str2,
    support_print_str2_callback *elprint_str2,
    support_print_str2_callback *tprint_str2,
    support_get_thread_id_callback *get_thread_id,
    void *callback_arg);
TSupportDbContext* _SUPPORT_CALLBACK_CONV
dbtrace_print_init2(void *info, const DCHAR *module, unsigned level,
    unsigned format);

DWORD _SUPPORT_CALLBACK_CONV
dbtrace_print_done_ex(TSupportDbContext* ctx);
DWORD _SUPPORT_CALLBACK_CONV
dbtrace_print_done(TSupportDbContext* ctx);
void* _SUPPORT_CALLBACK_CONV
dbtrace_print_callback_arg( TSupportDbContext* ctx );

int _SUPPORT_CALLBACK_CONV
dbtrace_print_is(TSupportDbContext* ctx, unsigned when);


#if defined _DEBUG || !defined ( _WIN32 )//на *nix отложенная инициализация лога - зачем это сделано - выяснить не удалось
#define dbtrace_print_qis_N_DB_ERROR(ctx, ...) ((ctx) && dbtrace_print_is(ctx, DB_PRINT_MASK(N_DB_ERROR)))
#define dbtrace_print_qis_N_DB_TRACE(ctx, ...) ((ctx) && dbtrace_print_is(ctx, DB_PRINT_MASK(N_DB_TRACE)))
#define dbtrace_print_qis_N_DB_CALL(ctx, ...) ((ctx) && dbtrace_print_is(ctx, DB_PRINT_MASK(N_DB_CALL)))
#define dbtrace_print_qis_N_DB_LOG(ctx, ...) ((ctx) && dbtrace_print_is(ctx, DB_PRINT_MASK(N_DB_LOG)))
#define dbtrace_print_qis_N_DB_WARN(ctx, ...) ((ctx) && dbtrace_print_is(ctx, DB_PRINT_MASK(N_DB_WARN)))
#define dbtrace_print_qis_N_DB_DEBUG(ctx, ...) ((ctx) && dbtrace_print_is(ctx, DB_PRINT_MASK(N_DB_DEBUG)))
#define dbtrace_print_qis_N_DB_CRUCIAL(ctx, ...) ((ctx) && dbtrace_print_is(ctx, DB_PRINT_MASK(N_DB_CRUCIAL)))
#else /*defined _DEBUG*/
#define dbtrace_print_qis_N_DB_ERROR(ctx, ...) ((ctx) && (*(unsigned*)(ctx)&DB_PRINT_MASK(N_DB_ERROR)))
#define dbtrace_print_qis_N_DB_TRACE(ctx, ...) ((ctx) && (*(unsigned*)(ctx)&DB_PRINT_MASK(N_DB_TRACE)))
#define dbtrace_print_qis_N_DB_CALL(ctx, ...) ((ctx) && (*(unsigned*)(ctx)&DB_PRINT_MASK(N_DB_CALL)))
#define dbtrace_print_qis_N_DB_LOG(ctx, ...) ((ctx) && (*(unsigned*)(ctx)&DB_PRINT_MASK(N_DB_LOG)))
#define dbtrace_print_qis_N_DB_WARN(ctx, ...) ((ctx) && (*(unsigned*)(ctx)&DB_PRINT_MASK(N_DB_WARN)))
#define dbtrace_print_qis_N_DB_DEBUG(ctx, ...) ((ctx) && (*(unsigned*)(ctx)&DB_PRINT_MASK(N_DB_DEBUG)))
#define dbtrace_print_qis_N_DB_CRUCIAL(ctx, ...) ((ctx) && (*(unsigned*)(ctx)&DB_PRINT_MASK(N_DB_CRUCIAL)))
#endif /*defined _DEBUG*/

#if defined __GNUC__ && !(defined PROCESSOR_TYPE && PROCESSOR_TYPE == PROC_TYPE_E2K64)
#define PRINTF_LIKE_FORMAT(string_index, first_to_check) \
    __attribute__ ((format (printf, (string_index), (first_to_check))))
#else // __GNUC__ && !PROC_TYPE_E2K64
#define PRINTF_LIKE_FORMAT(string_index, first_to_check)
#endif // __GNUC__ && !PROC_TYPE_E2K64

DWORD
dbtrace_cprint_print(TSupportDbContext* ctx, const DCHAR *str,
		     const DCHAR *file, int line, const DCHAR *func,
		     va_list args);
DWORD
dbtrace_dprint_print(TSupportDbContext* ctx, const DCHAR *str,
		     const DCHAR *file, int line, const DCHAR *func,
		     va_list args);
DWORD
dbtrace_eprint_print(TSupportDbContext* ctx, const DCHAR *str,
		     const DCHAR *file, int line, const DCHAR *func,
		     va_list args);
DWORD
dbtrace_elprint_print(TSupportDbContext* ctx, const DCHAR *str,
		      const DCHAR *file, int line, const DCHAR *func,
		      va_list args);
//+V576, function:dbtrace_cprint_print_, format_arg:2, ellipsis_arg:6
void
dbtrace_cprint_print_(TSupportDbContext* ctx, const DCHAR *str,
		      const DCHAR *file, int line, const DCHAR *func, ...) PRINTF_LIKE_FORMAT(2, 6);
//+V576, function:dbtrace_dprint_print_, format_arg:2, ellipsis_arg:6
void
dbtrace_dprint_print_(TSupportDbContext* ctx, const DCHAR *str, 
		      const DCHAR *file, int line, const DCHAR *func, ...) PRINTF_LIKE_FORMAT(2, 6);
//+V576, function:dbtrace_eprint_print_, format_arg:2, ellipsis_arg:6
void
dbtrace_eprint_print_(TSupportDbContext* ctx, const DCHAR *str,
		      const DCHAR *file, int line, const DCHAR *func, ...) PRINTF_LIKE_FORMAT(2, 6);
//+V576, function:dbtrace_elprint_print_, format_arg:2, ellipsis_arg:6
void
dbtrace_elprint_print_(TSupportDbContext* ctx, const DCHAR *str,
		       const DCHAR *file, int line, const DCHAR *func, ...) PRINTF_LIKE_FORMAT(2, 6);
//+V576, function:dbtrace_print_, format_arg:3, ellipsis_arg:9
static SUP_INLINE
void
dbtrace_print_(TSupportDbContext* ctx, int level, const DCHAR *str, void *info, size_t size,
    const DCHAR *file, int line, const DCHAR *func, ...) PRINTF_LIKE_FORMAT(3, 9);

#include <stdarg.h>

DWORD 
_SUPPORT_CALLBACK_CONV
dbtrace_print(TSupportDbContext* ctx, int level, const DCHAR *str, void *info, size_t size,
    const DCHAR *file, int line, const DCHAR *func,
    va_list args);

static SUP_INLINE
void
dbtrace_print_(TSupportDbContext* ctx, int level, const DCHAR *str, void *info, size_t size,
    const DCHAR *file, int line, const DCHAR *func, ...)
{
    va_list valist;					    
    va_start(valist, func);				    
    /*пока теряю информацию о направлении лога*/	    
    dbtrace_print(ctx, level, str, info, size, file, line, func, valist);
    va_end(valist);
}

#if 0 // не закочил deparen, сломался на solaris: https://jira.cp.ru/browse/CPCSP-10648?focusedCommentId=129025&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-129025
static SUP_INLINE void
dbtrace_print_level(int level, TSupportDbContext* ctx, const DCHAR *str,
    const DCHAR *file, int line, const DCHAR *func, ...) PRINTF_LIKE_FORMAT(3, 7);

static SUP_INLINE void
dbtrace_print_level(int level, TSupportDbContext* ctx, const DCHAR *str,
    const DCHAR *file, int line, const DCHAR *func, ...)
{
    va_list valist;
    va_start(valist, func);
    /*пока теряю информацию о направлении лога*/
    dbtrace_print(ctx, level, str, NULL, 0, file, line, func, valist);
    va_end(valist);
#endif

//Трёхэтажные макросы - зато не меняю вызывающий код
// макрос для PVS в общем виде не пишется
#define MAGIC_PRINT_FUNCTION(name, level)		    \
static SUP_INLINE void					    \
name##_##level(TSupportDbContext* ctx, const DCHAR *str,    \
    const DCHAR *file, int line, const DCHAR *func, ...) PRINTF_LIKE_FORMAT(2, 6); \
static SUP_INLINE void						    \
name##_##level(TSupportDbContext* ctx, const DCHAR *str,\
    const DCHAR *file, int line, const DCHAR *func, ...)    \
{							    \
    va_list valist;					    \
    va_start(valist, func);				    \
    /*пока теряю информацию о направлении лога*/	    \
    dbtrace_print(ctx, level, str, NULL, 0, file, line, func, valist);	    \
    va_end(valist);					    \
}

#define MAGIC_PRINT_FUNCTIONS(name)	\
MAGIC_PRINT_FUNCTION(name, N_DB_ERROR)	\
MAGIC_PRINT_FUNCTION(name, N_DB_WARN)	\
MAGIC_PRINT_FUNCTION(name, N_DB_CALL)	\
MAGIC_PRINT_FUNCTION(name, N_DB_LOG)	\
MAGIC_PRINT_FUNCTION(name, N_DB_TRACE)	\
MAGIC_PRINT_FUNCTION(name, N_DB_DEBUG)	\
MAGIC_PRINT_FUNCTION(name, N_DB_CRUCIAL)

MAGIC_PRINT_FUNCTIONS(dbtrace_cprint_print)
MAGIC_PRINT_FUNCTIONS(dbtrace_dprint_print)
MAGIC_PRINT_FUNCTIONS(dbtrace_eprint_print)
MAGIC_PRINT_FUNCTIONS(dbtrace_elprint_print)
MAGIC_PRINT_FUNCTIONS(dbtrace_tprint_print)

DWORD
_SUPPORT_CALLBACK_CONV
dbtrace_dprint_hex(TSupportDbContext *ctx, const DCHAR *file, int line,
		   const DCHAR *func, const DCHAR *msg, void *info, size_t size);
DWORD
_SUPPORT_CALLBACK_CONV
dbtrace_cprint_hex(TSupportDbContext *ctx, const DCHAR *file, int line,
		   const DCHAR *func, const DCHAR *msg, void *info, size_t size);
DWORD
_SUPPORT_CALLBACK_CONV
dbtrace_eprint_hex(TSupportDbContext *ctx, const DCHAR *file, int line,
		   const DCHAR *func, const DCHAR *msg, void *info, size_t size);
DWORD
_SUPPORT_CALLBACK_CONV
dbtrace_elprint_hex(TSupportDbContext *ctx, const DCHAR *file, int line,
		    const DCHAR *func, const DCHAR *msg, void *info, size_t size);

#ifdef __cplusplus
}
#endif

#endif /* DPRINT_H_INCLUDED */
