/** @file sanei_debug.h * Support for printing debug messages. * * Use the functions of this header file to print debug or warning messages. */ #ifndef _SANEI_DEBUG_H #define _SANEI_DEBUG_H #include /** @name Public macros * These macros can be used in backends and other SANE-related * code. * * Before including sanei_debug.h, the following macros must be set: * * - BACKEND_NAME - The name of your backend without double-quotes (must be set in any case) * - STUBS - If this is defined, no macros will be included. Used in * backends consisting of more than one .c file. * - DEBUG_DECLARE_ONLY - Generates prototypes instead of functions. Used in * backends consisting of more than one .c file. * - DEBUG_NOT_STATIC - Doesn't generate static functions. Used in header files if * they are include in more than one .c file. * * @{ */ /** @def DBG_INIT() * Initialize sanei_debug. * * Call this function before you use any DBG function. */ /** @def DBG(level, fmt, ...) * Print a message at debug level `level' or higher using a printf-like * function. Example: DBG(1, "sane_open: opening fd \%d\\n", fd). * * @param level debug level * @param fmt format (see man 3 printf for details) * @param ... additional arguments */ /** @def IF_DBG(x) * Compile code only if debugging is enabled. * * Expands to x if debug support is enabled at compile-time. If NDEBUG is * defined at compile-time this macro expands to nothing. * * @param x code to expand when debugging is enabled */ /** * @def DBG_LEVEL * Current debug level. * * You can only read this "variable". */ /** @def ENTRY(name) * Expands to sane_BACKEND_NAME_name. * * Example: ENTRY(init) in mustek.c will expand to sane_mustek_init. */ /* @} */ /** @hideinitializer*/ #define ENTRY(name) PASTE(PASTE(PASTE(sane_,BACKEND_NAME),_),name) #ifdef NDEBUG extern void sanei_debug_ndebug (int level, const char *msg, ...); # define DBG_LEVEL (0) # define DBG_INIT() # define DBG sanei_debug_ndebug # define IF_DBG(x) #else /* !NDEBUG */ /** @hideinitializer*/ # define DBG_LEVEL PASTE(sanei_debug_,BACKEND_NAME) # if defined(BACKEND_NAME) && !defined(STUBS) # ifdef DEBUG_DECLARE_ONLY extern int DBG_LEVEL; # else /* !DEBUG_DECLARE_ONLY */ int DBG_LEVEL = 0; # endif /* DEBUG_DECLARE_ONLY */ # endif /* BACKEND_NAME && !STUBS */ /** @hideinitializer*/ # define DBG_INIT() \ sanei_init_debug (STRINGIFY(BACKEND_NAME), &DBG_LEVEL) /** @hideinitializer*/ # define DBG_LOCAL PASTE(DBG_LEVEL,_call) # ifndef STUBS # ifdef DEBUG_DECLARE_ONLY extern void DBG_LOCAL (int level, const char *msg, ...) #ifdef __GNUC__ __attribute__ ((format (printf, 2, 3))) #endif ; # else /* !DEBUG_DECLARE_ONLY */ # include extern void sanei_debug_msg (int level, int max_level, const char *be, const char *fmt, va_list ap); #ifdef __GNUC__ # ifndef DEBUG_NOT_STATIC static # endif /* !DEBUG_NOT_STATIC */ void DBG_LOCAL (int level, const char *msg, ...) __attribute__ ((format (printf, 2, 3))); #endif /* __GNUC__ */ # ifndef DEBUG_NOT_STATIC static # endif /* !DEBUG_NOT_STATIC */ void DBG_LOCAL (int level, const char *msg, ...) { va_list ap; va_start (ap, msg); sanei_debug_msg (level, DBG_LEVEL, STRINGIFY(BACKEND_NAME), msg, ap); va_end (ap); } # endif /* DEBUG_DECLARE_ONLY */ # endif /* !STUBS */ /** @hideinitializer*/ # define DBG DBG_LOCAL extern void sanei_init_debug (const char * backend, int * debug_level_var); /** @hideinitializer*/ # define IF_DBG(x) x #endif /* NDEBUG */ #endif /* _SANEI_DEBUG_H */