I wish I could say I came up with the below, and I suppose I did, but I more or less gathered two or three techniques I didn’t come up with into a few lines to code to make a macro useful for debugging. Its primary merits are readable output and extreme ease of use.
#define MY_MODULE_DEBUG_CATEGORY1 0x0001 #define MY_MODULE_DEBUG_CATEGORY2 0x0002 #define MY_MODULE_DEBUG_CATEGORY3 0x0004 #if !defined(MY_MODULE_DEBUG) # define MY_MODULE_DEBUG 0x0000 #endif #define _pp_string(x) #x #define _pp_str(x) _pp_string(x) #if (__GNUC__ > 3) # define dbg(cat, fmt, ...) \ do { \ if (MY_MODULE_DEBUG_##cat & MY_MODULE_DEBUG) \ { \ printf(__FILE__":"_pp_str(__LINE__)" [%s] "fmt, \ __func__, ##__VA_ARGS__); \ } \ } while (0) #else # define dbg(cat, fmt, args...) \ do { \ if (MY_MODULE_DEBUG_ ## cat & MY_MODULE_DEBUG) \ { \ printf(__FILE__":"_pp_str(__LINE__)" [%s] "fmt, \ __FUNCTION__ , ##args); \ } \ } while (0) #endif #if defined(_SOME_OS_) # define os_err(cat, errval) \ do { \ char *errstr = 0; \ error_string(errval, &errstr, 80, ERR_GET_ALL); \ if (errstr) \ { \ dbg(cat, "OS ERROR:\n%s\n", errstr); \ free(errstr); \ } \ else \ { \ dbg(cat, "OS ERROR: %#lx - err_string() failed!\n", \ errval); \ } \ } while (0) #endif
Notice the “os_err” macro above, for use with OS-specific error string functions. This particular incantation is oriented toward a particular OS I interact with at work (names changed to protect the innocent), but the same idea would be applicable to any system, really.