--- a/src/log.c Fri May 08 01:42:44 2009 +0300
+++ b/src/log.c Fri May 08 01:43:02 2009 +0300
@@ -72,11 +72,7 @@
_log_output_ctx.arg = arg;
}
-/**
- * Format the full output line, and pass it to the log_output_func. The line will be of the form:
- * "[<level>] <func> : <log_fmt> [ <user_fmt> ]"
- */
-static void log_output (enum log_level level, const char *func, const char *user_fmt, va_list user_fmtargs, const char *log_fmt, ...)
+void log_output_tag (enum log_level level, const char *tag, const char *func, const char *user_fmt, va_list user_fmtargs, const char *log_fmt, ...)
{
char buf[LOG_MSG_MAX], *buf_ptr = buf;
size_t buf_size = sizeof(buf);
@@ -86,7 +82,7 @@
return;
// output the header
- buf_ptr += str_advance(NULL, &buf_size, str_append_fmt(buf_ptr, buf_size, "[%5s] %20s : ", log_level_name(level), func));
+ buf_ptr += str_advance(NULL, &buf_size, str_append_fmt(buf_ptr, buf_size, "[%5s] %20s : ", tag, func));
// output the user data
buf_ptr += str_advance(NULL, &buf_size, str_append_fmt_va(buf_ptr, buf_size, user_fmt, user_fmtargs));
@@ -110,7 +106,7 @@
// formatted output: no suffix
va_start(vargs, format);
- log_output(level, func, format, vargs, NULL);
+ log_output_tag(level, log_level_name(level), func, format, vargs, NULL);
va_end(vargs);
}
@@ -120,7 +116,7 @@
// formatted output: suffix error_name()
va_start(vargs, format);
- log_output(level, func, format, vargs, ": %s", error_name(err));
+ log_output_tag(level, log_level_name(level), func, format, vargs, ": %s", error_name(err));
va_end(vargs);
}
@@ -130,7 +126,7 @@
// formatted output: suffix error_msg()
va_start(vargs, format);
- log_output(level, func, format, vargs, ": %s", error_msg(err));
+ log_output_tag(level, log_level_name(level), func, format, vargs, ": %s", error_msg(err));
va_end(vargs);
}
@@ -140,7 +136,7 @@
// formatted output: suffix strerror()
va_start(vargs, format);
- log_output(level, func, format, vargs, ": %s", strerror(errno));
+ log_output_tag(level, log_level_name(level), func, format, vargs, ": %s", strerror(errno));
va_end(vargs);
}
--- a/src/log.h Fri May 08 01:42:44 2009 +0300
+++ b/src/log.h Fri May 08 01:43:02 2009 +0300
@@ -6,6 +6,7 @@
* Local logging functions
*/
#include "error.h"
+#include <stdarg.h>
/**
* Log level definitions
@@ -53,6 +54,15 @@
void log_set_func (log_output_func func, void *arg);
/**
+ * Internal logging func, meant for using custom level tags. This performs the filtering of log levels.
+ *
+ * Format the full output line, and pass it to the log_output_func. The line will be of the form:
+ * "[<tag>] <func> : <user_fmt> [ <log_fmt> ]"
+ */
+void log_output_tag (enum log_level level, const char *tag, const char *func, const char *user_fmt, va_list user_fmtargs, const char *log_fmt, ...)
+ __attribute__ ((format (printf, 6, 7)));
+
+/**
* Log a message with the given level
*/
void log_msg (enum log_level level, const char *func, const char *format, ...)
--- a/src/test/assert.c Fri May 08 01:42:44 2009 +0300
+++ b/src/test/assert.c Fri May 08 01:43:02 2009 +0300
@@ -1,70 +1,62 @@
#include "assert.h"
#include "util.h"
-#include "backtrace.h"
#include <string.h>
-#define ASSERT_FAIL(...) do { log_fatal(__VA_ARGS__); test_backtrace(1); abort(); } while (0)
-void assert_true (bool cond, const char *msg)
+#define _ASSERT_FUNC_FAIL(...) test_fail(func, file, line, 1, __VA_ARGS__)
+
+void _assert_null (_ASSERT_FUNC_ARGS, const void *ptr)
{
- if (!cond)
- ASSERT_FAIL("%s", msg);
+ if (ptr)
+ _ASSERT_FUNC_FAIL("%p != NULL", ptr);
}
-void assert_null (const void *ptr)
-{
- if (ptr)
- ASSERT_FAIL("%p != NULL", ptr);
-}
-
-void assert_strcmp (const char *is, const char *should_be)
+void _assert_strcmp (_ASSERT_FUNC_ARGS, const char *is, const char *should_be)
{
if (!should_be && !is)
return;
-
+
if (!is || strcmp(is, should_be))
- ASSERT_FAIL("%s != %s", dump_str(is), dump_str(should_be));
-}
-
-void assert_strncmp (const char *is, const char *should_be, size_t n)
-{
- if (!should_be && !is)
- return;
-
- if (!is || strncmp(is, should_be, n))
- ASSERT_FAIL("%s:%u != %s", dump_strn(is, n), (unsigned) n, dump_strn(should_be, n));
-}
-
-void assert_strlen (const char *str, size_t n)
-{
- if (!str || strlen(str) != n)
- ASSERT_FAIL("strlen(%s) != %u", dump_str(str), (unsigned) n);
+ _ASSERT_FUNC_FAIL("%s != %s", dump_str(is), dump_str(should_be));
}
-void assert_strnull (const char *str)
+void _assert_strncmp (_ASSERT_FUNC_ARGS, const char *is, const char *should_be, size_t n)
{
- if (str != NULL)
- ASSERT_FAIL("%s != NULL", dump_str(str));
-}
-
-void assert_success (err_t err)
-{
- if (err != SUCCESS)
- ASSERT_FAIL("error: %s", error_name(err));
+ if (!should_be && !is)
+ return;
+
+ if (!is || strncmp(is, should_be, n))
+ _ASSERT_FUNC_FAIL("%s:%u != %s", dump_strn(is, n), (unsigned) n, dump_strn(should_be, n));
}
-void assert_err (err_t err, err_t target)
+void _assert_strlen (_ASSERT_FUNC_ARGS, const char *str, size_t n)
{
- if (err != target)
- ASSERT_FAIL("error: <%s> != <%s>", error_name(err), error_name(target));
+ if (!str || strlen(str) != n)
+ _ASSERT_FUNC_FAIL("strlen(%s) != %u", dump_str(str), (unsigned) n);
}
-void assert_error (error_t *is, error_t *should_be)
+void _assert_strnull (_ASSERT_FUNC_ARGS, const char *str)
+{
+ if (str)
+ _ASSERT_FUNC_FAIL("%s != NULL", dump_str(str));
+}
+
+void _assert_success (_ASSERT_FUNC_ARGS, err_t err)
+{
+ if (err)
+ _ASSERT_FUNC_FAIL("err: %s", dump_str(error_name(err)));
+}
+
+void _assert_err (_ASSERT_FUNC_ARGS, err_t is, err_t should_be)
+{
+ if (is != should_be)
+ _ASSERT_FUNC_FAIL("err: %s != %s", dump_str(error_name(is)), dump_str(error_name(should_be)));
+}
+
+void _assert_error (_ASSERT_FUNC_ARGS, error_t *is, error_t *should_be)
{
if (ERROR_CODE(is) != ERROR_CODE(should_be) || ERROR_EXTRA(is) != ERROR_EXTRA(should_be))
- // XXX: dual use of error_msg
- ASSERT_FAIL("error: <%s> != <%s>", error_msg(is), error_msg(should_be));
+ _ASSERT_FUNC_FAIL("error: %s != %s", dump_str(error_msg(is)), dump_str(error_msg(should_be)));
+
}
-
-
--- a/src/test/assert.h Fri May 08 01:42:44 2009 +0300
+++ b/src/test/assert.h Fri May 08 01:43:02 2009 +0300
@@ -6,58 +6,76 @@
*
* Various general assert-condition tests used to fail tests
*/
+#include "fail.h"
#include "../error.h"
-#include "../log.h"
/*
* Also accept the existance of the system assert() function
*/
#include <assert.h>
-#include <stdbool.h>
+
+/*
+ * Internal shorthand macros for passing func/file/line args
+ */
+#define _ASSERT_FUNC_ARGS const char *func, const char *file, int line
+#define _ASSERT_FUNC_CALL(func, ...) func(__func__, __FILE__, __LINE__, __VA_ARGS__)
/**
* Assert that the given condition is true, and fail with the given error if not
*/
-void assert_true (bool cond, const char *msg);
+#define assert_true(cond, ...) fail_if(cond, __VA_ARGS__)
+
+/**
+ * Assert failure unconditionally
+ */
+#define assert_fail(...) fail(__VA_ARGS__)
/**
* Assert that the given pointer value is NULL.
*/
-void assert_null (const void *ptr);
+#define assert_null(ptr) _ASSERT_FUNC_CALL(_assert_null, ptr)
+void _assert_null (_ASSERT_FUNC_ARGS, const void *ptr);
/**
* Assert that the given NUL-terminated string matches the given target string exactly.
*/
-void assert_strcmp (const char *is, const char *should_be);
+#define assert_strcmp(is, should_be) _ASSERT_FUNC_CALL(_assert_strcmp, is, should_be)
+void _assert_strcmp (_ASSERT_FUNC_ARGS, const char *is, const char *should_be);
/**
* Assert that the first \a n chars of the first string matches the second string exactly.
*/
-void assert_strncmp (const char *is, const char *should_be, size_t n);
+#define assert_strncmp(is, should_be, n) _ASSERT_FUNC_CALL(_assert_strncmp, is, should_be, n)
+void _assert_strncmp (_ASSERT_FUNC_ARGS, const char *is, const char *should_be, size_t n);
/**
* Assert that the given \a str is \a n chars long.
*/
-void assert_strlen (const char *str, size_t n);
+#define assert_strlen(str, n) _ASSERT_FUNC_CALL(_assert_strlen, str, n)
+void _assert_strlen (_ASSERT_FUNC_ARGS, const char *str, size_t n);
/**
* Assert that the given \a str is NULL.
*/
-void assert_strnull (const char *str);
+#define assert_strnull(str) _ASSERT_FUNC_CALL(_assert_strnull, str)
+void _assert_strnull (_ASSERT_FUNC_ARGS, const char *str);
/**
* Assert that the given error code is SUCCESS.
*/
-void assert_success (err_t err);
+#define assert_success(err) _ASSERT_FUNC_CALL(_assert_success, err)
+void _assert_success (_ASSERT_FUNC_ARGS, err_t err);
/**
- * Assert that the given actual error code \a err matches the expected error code \target.
+ * Assert that the given actual error code \a err matches the expected error code \a should_be.
*/
-void assert_err (err_t err, err_t target);
+#define assert_err(is, should_be) _ASSERT_FUNC_CALL(_assert_err, is, should_be)
+void _assert_err (_ASSERT_FUNC_ARGS, err_t is, err_t should_be);
/**
* Assert that the given actual error \a is matches the expected error \a should_be
*/
-void assert_error (error_t *is, error_t *should_be);
+#define assert_error(is, should_be) _ASSERT_FUNC_CALL(_assert_error, is, should_be)
+void _assert_error (_ASSERT_FUNC_ARGS, error_t *is, error_t *should_be);
#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/fail.c Fri May 08 01:43:02 2009 +0300
@@ -0,0 +1,30 @@
+#include "fail.h"
+#include "../str.h"
+#include "../log.h"
+#include "backtrace.h"
+
+#include <stdarg.h>
+
+void test_fail_va (const char *func, const char *file, int line, int skip, const char *fmt, va_list vargs)
+{
+ // log it
+ log_output_tag(LOG_ERROR, "FAIL", func, fmt, vargs, " @@ %s@%s:%d - backtrace follows:", func, file, line);
+
+ // print out a stack dump, not including this function or the backtrace func
+ test_backtrace(skip + 2);
+
+ // then exit with a failure code
+ abort();
+}
+
+void test_fail (const char *func, const char *file, int line, int skip, const char *fmt, ...)
+{
+ va_list vargs;
+
+ va_start(vargs, fmt);
+
+ test_fail_va(func, file, line, skip, fmt, vargs);
+
+ va_end(vargs);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/fail.h Fri May 08 01:43:02 2009 +0300
@@ -0,0 +1,50 @@
+#ifndef TEST_FAIL_H
+#define TEST_FAIL_H
+
+/**
+ * @file
+ *
+ * Various ways to mark the current test as failed.
+ */
+#include "../error.h"
+#include <stdarg.h>
+
+#define NORETURN __attribute((noreturn))
+
+/**
+ * Output a message representing the given failure using log_output.
+ *
+ * Also dumps out a stacktrace for the calling function using log_debug, skipping this func, the backtrace func, and
+ * the given number of frames.
+ */
+void test_fail_va (const char *func, const char *file, int line, int skip, const char *fmt, va_list vargs) NORETURN;
+
+/**
+ * Output given fail using test_fail_va().
+ */
+void test_fail (const char *func, const char *file, int line, int skip, const char *fmt, ...) NORETURN;
+
+/**
+ * Fail with a simply error message
+ */
+#define fail(...) test_fail(__func__, __FILE__, __LINE__, 0, __VA_ARGS__)
+
+/**
+ * Fail conditionally
+ */
+#define fail_if(cond, ...) do { \
+ if (cond) \
+ fail(__VA_ARGS__); \
+ } while (0)
+
+/**
+ * Fail with an error code
+ */
+#define fail_err(err, fmt, ...) fail(fmt ": %s", __VA_ARGS__, ## error_name(err))
+
+/**
+ * Fail with an error info
+ */
+#define fail_error(error, fmt, ...) fail(fmt ": %s", __VA_ARGS__, ## error_msg(error))
+
+#endif /* TEST_FAIL_H */
--- a/src/test/test.h Fri May 08 01:42:44 2009 +0300
+++ b/src/test/test.h Fri May 08 01:43:02 2009 +0300
@@ -9,8 +9,11 @@
#include "assert.h"
#include "util.h"
+#include "../log.h"
+
#include <event2/event.h>
#include <string.h>
+#include <stdbool.h>
/**
* Global test-running state