return pass;
}
+static void print_mem(FILE* stream, void const* data, size_t size)
+{
+ if (data == NULL)
+ {
+ fprintf(stream, "NULL");
+ return;
+ }
+
+ if (size == 0)
+ {
+ fprintf(stream, "(no bytes)");
+ return;
+ }
+
+ uint8_t const* byte_data = data;
+
+ fprintf(stream, "x'");
+
+ for (size_t i = 0; i < size; ++i)
+ {
+ fprintf(stream, "%02x", (unsigned int)byte_data[i]);
+ }
+
+ fprintf(stream, "'");
+}
+
+bool libtest_check_mem(char const* file, int line, bool pass, void const* lhs, void const* rhs, size_t size,
+ char const* lhs_str, char const* op_str, char const* rhs_str)
+{
+ if (should_print(pass))
+ {
+ fprintf(stderr, "%s %s:%d: %s %s %s (", pass ? "PASS" : "FAIL", file, line, lhs_str, op_str, rhs_str);
+ print_mem(stderr, lhs, size);
+ fprintf(stderr, " %s ", op_str);
+ print_mem(stderr, rhs, size);
+ fprintf(stderr, ")\n");
+ }
+
+ return pass;
+}
+
bool libtest_check_int(char const* file, int line, bool pass, intmax_t lhs, intmax_t rhs, char const* lhs_str,
char const* op_str, char const* rhs_str)
{
char const* rhs_str);
bool libtest_check_str(char const* file, int line, bool pass, char const* lhs, char const* rhs, char const* lhs_str,
char const* op_str, char const* rhs_str);
+bool libtest_check_mem(char const* file, int line, bool pass, void const* lhs, void const* rhs, size_t size,
+ char const* lhs_str, char const* op_str, char const* rhs_str);
bool libtest_check_int(char const* file, int line, bool pass, intmax_t lhs, intmax_t rhs, char const* lhs_str,
char const* op_str, char const* rhs_str);
bool libtest_check_uint(char const* file, int line, bool pass, uintmax_t lhs, uintmax_t rhs, char const* lhs_str,
} \
while (0)
+#define check_mem(lhs, op, rhs, size) \
+ do \
+ { \
+ ++current_test; \
+ \
+ void const* const check_mem_lhs = (lhs); \
+ void const* const check_mem_rhs = (rhs); \
+ size_t const check_mem_size = (size);\
+ \
+ if (!libtest_check_mem(__FILE__, __LINE__, tr_memcmp0(check_mem_lhs, check_mem_rhs, check_mem_size) op 0, \
+ check_mem_lhs, check_mem_rhs, check_mem_size, #lhs, #op, #rhs)) \
+ { \
+ return current_test; \
+ } \
+ } \
+ while (0)
+
#define check_int(lhs, op, rhs) \
do \
{ \
return 0;
}
+int tr_memcmp0(void const* lhs, void const* rhs, size_t size)
+{
+ if (lhs != NULL && rhs != NULL)
+ {
+ return memcmp(lhs, rhs, size);
+ }
+
+ if (lhs != NULL)
+ {
+ return 1;
+ }
+
+ if (rhs != NULL)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
/****
*****
****/
*/
int tr_strcmp0(char const* str1, char const* str2);
+/**
+ * @brief like memcmp() but gracefully handles NULL pointers
+ */
+int tr_memcmp0(void const* lhs, void const* rhs, size_t size);
+
char* evbuffer_free_to_str(struct evbuffer* buf, size_t* result_len);
/** @brief similar to bsearch() but returns the index of the lower bound */