265 lines
11 KiB
C
265 lines
11 KiB
C
/*
|
|
* Copyright (c) 2005, 2006 by KoanLogic s.r.l. - All rights reserved.
|
|
*/
|
|
|
|
#ifndef _U_CARPAL_H_
|
|
#define _U_CARPAL_H_
|
|
|
|
#include <sys/types.h>
|
|
#ifdef TIME_WITH_SYS_TIME
|
|
#include <sys/time.h>
|
|
#endif
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <stdarg.h>
|
|
|
|
|
|
#include <u/log.h>
|
|
#include "./debug_internal.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define msg(label, ...) label( __VA_ARGS__)
|
|
#define msg_noargs(label, literal) label("%s", literal)
|
|
|
|
/** \brief log a message and goto "err" label
|
|
*
|
|
* log a message of type \e label if \e expr not zero.
|
|
*
|
|
*/
|
|
#define msg_err(label, ...) do { msg(label, __VA_ARGS__); goto err; } while(0)
|
|
|
|
/** \brief log a message if \e expr not zero.
|
|
*
|
|
* log a message of type \e label if \e expr is not zero
|
|
*
|
|
* \e expr text statement will be written to the log file.
|
|
*
|
|
* For ex.:
|
|
* warn_if(check(abc) < 0);
|
|
*/
|
|
#define msg_if(label, expr) do { if( expr ) msg_noargs(label, #expr); } while(0)
|
|
|
|
/** \brief log a message if \e expr not zero and enter the if-block
|
|
*
|
|
* log a message of type \e label if \e expr is not zero and enter the
|
|
* following if-block.
|
|
*
|
|
* \e expr text statement will be written to the log file.
|
|
*
|
|
* A C-style dbg_ code block should follow. For ex.:
|
|
* dbg_ifb(i == 0)
|
|
* {
|
|
* do_something();
|
|
* do_something();
|
|
* }
|
|
*/
|
|
#define msg_ifb(label, expr) if( (expr) && (msg_noargs(label, #expr) ? 1 : 1) )
|
|
|
|
/** \brief log a message if \e expr not zero and return \e err.
|
|
*
|
|
* log a message of type \e label if \e expr is not zero and return
|
|
* \e err to the caller.
|
|
*
|
|
* \e expr text statement will be written to the log file.
|
|
*
|
|
* Example:
|
|
* dbg_return_if(param == NULL, FUNC_ERROR);
|
|
*/
|
|
#define msg_return_if(label, expr, err) msg_ifb(label, expr) return err
|
|
|
|
/** \brief log a message if \e expr not zero and return \e err. (Log the strerror also)
|
|
*
|
|
* log a message of type \e label if \e expr is not zero and return
|
|
* \e err to the caller. Log also the strerror(errno).
|
|
*
|
|
* \e expr text statement will be written to the log file.
|
|
*/
|
|
#define msg_return_sif(label, expr, err) \
|
|
do { msg_ifb(label, expr) { msg_strerror(label, errno); return err; } } while(0)
|
|
|
|
/** \brief log a message if \e expr not zero and goto \e gt.
|
|
*
|
|
* log a message of type \e label if \e expr is not zero and goto
|
|
* to the label \e gt (that must be in-scope).
|
|
*
|
|
* \e expr text statement will be written to the log file.
|
|
*/
|
|
#define msg_goto_if(label, expr, gt) msg_ifb(label, expr) goto gt
|
|
|
|
/** \brief log a message if \e expr not zero and goto to the label "err"
|
|
*
|
|
* log a message of type \e label if \e expr is not zero and goto
|
|
* to the label "err" (that must be defined).
|
|
*
|
|
* \e expr text statement will be written to the log file.
|
|
*/
|
|
#define msg_err_if(label, expr) do { msg_ifb(label, expr) { goto err;} } while(0)
|
|
|
|
/** \brief log a message if \e expr not zero and goto to the label "err".
|
|
*
|
|
* log a message of type \e label if \e expr is not zero and goto
|
|
* to the label "err" (that must be defined). also logs arguments provided
|
|
* by the caller.
|
|
*/
|
|
#define msg_err_ifm(label, expr, ...) \
|
|
do { if( (expr) ) { msg(label, __VA_ARGS__); goto err; } } while(0)
|
|
|
|
/** \brief log a message if \e expr not zero and goto to the label "err".
|
|
*
|
|
* log a message of type \e label if \e expr is not zero and goto
|
|
* to the label "err" (that must be defined). also logs strerror(errno).
|
|
*/
|
|
#define msg_err_sif(label, expr) \
|
|
do { msg_ifb(label, expr) { msg_strerror(label, errno); goto err; } } while(0)
|
|
|
|
/** \brief write a debug message containing the message returned by strerror(errno) */
|
|
#ifdef WIN32
|
|
#define msg_strerror(label, en) \
|
|
do { \
|
|
LPVOID lpMsgBuf = NULL; DWORD dw = GetLastError(); \
|
|
if(FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | \
|
|
FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, \
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \
|
|
(LPTSTR) &lpMsgBuf, 0, NULL ) && lpMsgBuf) \
|
|
{ \
|
|
msg(label, "%s", lpMsgBuf); \
|
|
LocalFree(lpMsgBuf); \
|
|
} \
|
|
} while(0)
|
|
#else
|
|
#ifdef HAVE_STRERROR_R
|
|
#ifdef STRERROR_R_CHAR_P
|
|
#define msg_strerror(label, en) \
|
|
do { \
|
|
enum { _DBG_BUFSZ = 256 }; \
|
|
char *p, _eb[_DBG_BUFSZ] = { 0 }; \
|
|
p = strerror_r(en, _eb, _DBG_BUFSZ); \
|
|
if(p) { \
|
|
msg(label, "%s", p); \
|
|
} else { \
|
|
msg(label, "strerror_r(%d, ...) failed", en); \
|
|
} \
|
|
} while(0)
|
|
#else
|
|
#define msg_strerror(label, en) \
|
|
do { \
|
|
enum { _DBG_BUFSZ = 256 }; \
|
|
char _eb[_DBG_BUFSZ] = { 0 }; \
|
|
if(strerror_r(en, _eb, _DBG_BUFSZ) == 0) { \
|
|
msg(label, "%s", _eb); \
|
|
} else { \
|
|
msg(label, "strerror_r(%d, ...) failed", en); \
|
|
} \
|
|
} while(0)
|
|
#endif
|
|
#else
|
|
#define msg_strerror(label, en) \
|
|
do { \
|
|
char *p; \
|
|
if((p = strerror(en)) != NULL) { \
|
|
msg(label, "%s", p); \
|
|
} else { \
|
|
msg(label, "strerror(%d) failed", en); \
|
|
} \
|
|
} while(0)
|
|
#endif
|
|
#endif /* ! def WIN32 */
|
|
|
|
/* nop_ macros */
|
|
#define nop_return_if(expr, err) do { if(expr) return err; } while(0)
|
|
#define nop_err_if(expr) do { if(expr) goto err; } while(0)
|
|
#define nop_goto_if(expr, gt) do { if(expr) goto gt; } while(0)
|
|
|
|
/* con_ macros */
|
|
#define con(...) msg(console, __VA_ARGS__)
|
|
#define con_err(...) msg_err(console, __VA_ARGS__)
|
|
#define con_ifb(expr) msg_ifb(console, expr)
|
|
#define con_if(expr) msg_if(console, expr)
|
|
#define con_return_if(expr, err) msg_return_if(console, expr, err)
|
|
#define con_err_if(expr) msg_err_if(console, expr)
|
|
#define con_err_ifm(expr, ...) \
|
|
msg_err_ifm(console, expr, __VA_ARGS__)
|
|
#define con_goto_if(expr, gt) msg_goto_if(console, expr, gt)
|
|
#define con_strerror(errno) msg_strerror(console, errno)
|
|
|
|
/* info_ macros */
|
|
/* #define info(...) msg(_info, __VA_ARGS__) */
|
|
#define info_err(...) msg_err(_info, __VA_ARGS__)
|
|
#define info_ifb(expr) msg_ifb(_info, expr)
|
|
#define info_if(expr) msg_if(_info, expr)
|
|
#define info_return_if(expr, err) msg_return_if(_info, expr, err)
|
|
#define info_err_if(expr) msg_err_if(_info, expr)
|
|
#define info_err_sif(expr) msg_err_sif(_info, expr)
|
|
#define info_err_ifm(expr, ...) \
|
|
msg_err_ifm(_info, expr, __VA_ARGS__)
|
|
#define info_goto_if(expr, gt) msg_goto_if(_info, expr, gt)
|
|
#define info_strerror(errno) msg_strerror(_info, errno)
|
|
|
|
/* warn_ macros */
|
|
#define warn(...) msg(_warning, __VA_ARGS__)
|
|
#define warn_err(...) msg_err(_warning, __VA_ARGS__)
|
|
#define warn_ifb(expr) msg_ifb(_warning, expr)
|
|
#define warn_if(expr) msg_if(_warning, expr)
|
|
#define warn_return_if(expr, err) msg_return_if(_warning, expr, err)
|
|
#define warn_err_if(expr) msg_err_if(_warning, expr)
|
|
#define warn_err_sif(expr) msg_err_sif(_warning, expr)
|
|
#define warn_err_ifm(expr, ...) \
|
|
msg_err_ifm(_warning, expr, __VA_ARGS__)
|
|
#define warn_goto_if(expr, gt) msg_goto_if(_warning, expr, gt)
|
|
#define warn_strerror(errno) msg_strerror(_warning, errno)
|
|
|
|
/* dbg_ macros */
|
|
#ifdef DEBUG
|
|
#define dbg(...) msg(debug, __VA_ARGS__)
|
|
#define dbg_err(...) msg_err(debug, __VA_ARGS__)
|
|
#define dbg_ifb(expr) msg_ifb(debug, expr)
|
|
#define dbg_if(expr) msg_if(debug, expr)
|
|
#define dbg_return_if(expr, err) msg_return_if(debug, expr, err)
|
|
#define dbg_return_sif(expr, err) msg_return_sif(debug, expr, err)
|
|
#define dbg_err_if(expr) msg_err_if(debug, expr)
|
|
#define dbg_err_sif(expr) msg_err_sif(debug, expr)
|
|
#define dbg_err_ifm(expr, ...) \
|
|
msg_err_ifm(debug, expr, __VA_ARGS__)
|
|
#define dbg_goto_if(expr, gt) msg_goto_if(debug, expr, gt)
|
|
#define dbg_strerror(errno) msg_strerror(debug, errno)
|
|
/* simple debugging timing macros */
|
|
#define TIMER_ON \
|
|
time_t _t_beg = time(0), _t_prev = _t_beg, _t_now; int _t_step = 0
|
|
#define TIMER_STEP \
|
|
do { \
|
|
_t_now = time(0); \
|
|
dbg(" step %u: %u s (delta: %u s)", \
|
|
_t_step++, _t_now - _t_beg, _t_now - _t_prev); \
|
|
_t_prev = _t_now; \
|
|
} while(0)
|
|
#define TIMER_OFF dbg("elapsed: %u s", (time(0) - _t_beg))
|
|
#else /* disable debugging */
|
|
#include <ctype.h>
|
|
/* this will be used just to avoid empty-if (and similar) warnings */
|
|
#define dbg_nop()
|
|
#define dbg(...) dbg_nop()
|
|
#define dbg_err(...) do { goto err; } while(0)
|
|
#define dbg_ifb(expr) if( (expr) )
|
|
#define dbg_if(expr) expr
|
|
#define dbg_return_if(expr, err) do { if( (expr) ) return err; } while(0)
|
|
#define dbg_err_if(expr) do { if( (expr)) goto err; } while(0)
|
|
#define dbg_err_sif(expr) do { if( (expr)) goto err; } while(0)
|
|
#define dbg_err_ifm(expr, ...) do { if( (expr)) goto err; } while(0)
|
|
#define dbg_goto_if(expr, gt) do { if((expr)) goto gt; } while(0)
|
|
#define dbg_strerror(errno) dbg_nop()
|
|
#define TIMER_ON
|
|
#define TIMER_STEP
|
|
#define TIMER_OFF
|
|
#endif /* ifdef DEBUG */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* _U_CARPAL_H_ */
|
|
|