}
void __igt_skip_check(const char *file, const int line,
- const char *func, const char *check)
+ const char *func, const char *check,
+ const char *f, ...)
{
- igt_skip("Test requirement not met in function %s, file %s:%i:\n"
- "Test requirement: (%s)\n",
- func, file, line, check);
+ va_list args;
+
+ if (f) {
+ char buf[4096];
+ int length;
+
+ /*
+ * Important: va_list argument lists can't be used twice, so we
+ * can't first do an vsnprintf call to size the temporary
+ * storage correctly. Pick the easy solution with a static
+ * buffer and an asssert.
+ */
+ va_start(args, f);
+ length = vsnprintf(buf, sizeof(buf), f, args);
+ assert(length < sizeof(buf) - 1);
+ va_end(args);
+
+ igt_skip("Test requirement not met in function %s, file %s:%i:\n"
+ "Test requirement: (%s)\n%s",
+ func, file, line, check, buf);
+ } else {
+ igt_skip("Test requirement not met in function %s, file %s:%i:\n"
+ "Test requirement: (%s)\n",
+ func, file, line, check);
+ }
}
void igt_success(void)
}
void __igt_fail_assert(int exitcode, const char *file,
- const int line, const char *func, const char *assertion)
+ const int line, const char *func, const char *assertion,
+ const char *f, ...)
{
+ va_list args;
+
printf("Test assertion failure function %s, file %s:%i:\n"
"Failed assertion: %s\n",
func, file, line, assertion);
+
+ if (f) {
+ va_start(args, f);
+ vprintf(f, args);
+ va_end(args);
+ }
+
if (run_under_gdb())
abort();
igt_fail(exitcode);
*/
#define igt_tokencat2(x, y) x ## y
#define igt_tokencat(x, y) igt_tokencat2(x, y)
-#define __igt_subtest_f(tmp, format, args...) \
+#define __igt_subtest_f(tmp, format...) \
for (char tmp [256]; \
snprintf( tmp , sizeof( tmp ), \
- format, args), \
+ format), \
__igt_run_subtest( tmp ) && \
(setjmp(igt_subtest_jmpbuf) == 0); \
igt_success())
-#define igt_subtest_f(f, a...) \
- __igt_subtest_f(igt_tokencat(__tmpchar, __LINE__), f, a)
+#define igt_subtest_f(f...) \
+ __igt_subtest_f(igt_tokencat(__tmpchar, __LINE__), f)
#define igt_subtest(name) for (; __igt_run_subtest((name)) && \
(setjmp(igt_subtest_jmpbuf) == 0); \
igt_success())
* For normal tests without subtest it will directly exit.
*/
__attribute__((format(printf, 1, 2))) void igt_skip(const char *f, ...);
+__attribute__((format(printf, 5, 6)))
void __igt_skip_check(const char *file, const int line,
- const char *func, const char *check);
+ const char *func, const char *check,
+ const char *format, ...);
/**
* igt_success - complete a (subtest) as successfull
*
* presuming that some mandatory setup failed.
*/
void igt_fail(int exitcode) __attribute__((noreturn));
+__attribute__((format(printf, 6, 7)))
void __igt_fail_assert(int exitcode, const char *file,
- const int line, const char *func, const char *assertion)
+ const int line, const char *func, const char *assertion,
+ const char *format, ...)
__attribute__((noreturn));
/**
* igt_exit - exit() for igts
*
* Should be used everywhere where a test checks results.
*/
-#define igt_assert(expr) do { if (!(expr)) __igt_fail_assert(99, __FILE__, __LINE__, __func__, #expr ); } while (0)
+#define igt_assert(expr) \
+ do { if (!(expr)) \
+ __igt_fail_assert(99, __FILE__, __LINE__, __func__, #expr , NULL); \
+ } while (0)
+#define igt_assert_f(expr, f...) \
+ do { if (!(expr)) \
+ __igt_fail_assert(99, __FILE__, __LINE__, __func__, #expr , f); \
+ } while (0)
/**
* igt_require - skip a (sub-)test if a condition is not met
*
* code control flow.
*/
#define igt_require(expr) igt_skip_on(!(expr))
-#define igt_skip_on(expr) do { if ((expr)) __igt_skip_check(__FILE__, __LINE__, __func__, #expr ); } while (0)
+#define igt_skip_on(expr) \
+ do { if ((expr)) \
+ __igt_skip_check(__FILE__, __LINE__, __func__, #expr , NULL); \
+ } while (0)
+#define igt_require_f(expr, f...) igt_skip_on_f(!(expr), f)
+#define igt_skip_on_f(expr, f...) \
+ do { if ((expr)) \
+ __igt_skip_check(__FILE__, __LINE__, __func__, #expr , f); \
+ } while (0)
bool __igt_fixture(void);
void __igt_fixture_complete(void);