I would like to have ck_assert_mem macros for checking memory locations (similar to ck_assert_str).
Currently I'm using the following in my code:
inline char *tohex(const uint8_t *bin, size_t l)
{
char *buf = (char *)malloc(l * 2 + 1);
static char digits[] = "0123456789abcdef";
size_t i;
for (i = 0; i < l; i++) {
buf[i*2 ] = digits[(bin[i] >> 4) & 0xF];
buf[i*2+1] = digits[bin[i] & 0xF];
}
buf[l * 2] = 0;
return buf;
}
#define _ck_assert_mem(X, Y, L, OP) do { \
const void* _ck_x = (X); \
const void* _ck_y = (Y); \
size_t _ck_l = (L); \
ck_assert_msg(0 OP memcmp(_ck_y, _ck_x, _ck_l), \
"Assertion '"#X#OP#Y"' failed: "#X"==\"%s\", "#Y"==\"%s\"", tohex(_ck_x, _ck_l), tohex(_ck_y, _ck_l)); \
} while (0)
#define ck_assert_mem_eq(X, Y, L) _ck_assert_mem(X, Y, L, ==)
#define ck_assert_mem_ne(X, Y, L) _ck_assert_mem(X, Y, L, !=)
#define ck_assert_mem_lt(X, Y, L) _ck_assert_mem(X, Y, L, <)
#define ck_assert_mem_le(X, Y, L) _ck_assert_mem(X, Y, L, <=)
#define ck_assert_mem_gt(X, Y, L) _ck_assert_mem(X, Y, L, >)
#define ck_assert_mem_ge(X, Y, L) _ck_assert_mem(X, Y, L, >=)
The only thing I am not so sure about is the "tohex" function. There should be a better way how to achieve that, but I was not able to come up with any (that does not leak memory via malloc).
The idea of having this macro is worth exploring. Something will need to be done about the tohex() function though. For tests using fork mode, the memory will be free'd eventually when the process ends. no-fork mode, though, will keep the leaked memory until the end.
If the buffer is long enough, then the assertion output may be tough to read. Would it be a reasonable trade-off to make the printout of fixed length? That way, a constant size buffer could be used. For example, if tohex() accepted the buffer to write to as an argument:
This would have a few unfortunate draw-backs:
1) the printed string would be limited to an arbitrary size.
2) the buffers would need to be created every time, even when there is not a failure.
3) the buffer allocations would be on the stack. If the stack size on which the unit tests are running is limited, this may blow the stack.
Internally the function that ck_assert_msg() eventually calls has a locally allocated buffer for the resulting assertion string:
Likely the value of BUFSIZ may change from system to system. On mine the value is 8192. Probably point #3 is not that important, if ck_assert_msg() is working just fine. However, the size of the buffer string is limited at least by the BUFSIZ buffer. Maybe the fixed size buffers for the strings is not such a bad idea.
If you are interested in pursuing this further, would you be interested in coming up with a patch including unit tests and updates to documentation?
Last edit: Branden Archer 2013-12-18
We've not heard back from you with your feature request. If you would like to pursue thus further, consider submitting a pull request to Check from its new home:
https://github.com/libcheck/check