Blame ptunit/include/ptunit.h

Packit b1f7ae
/*
Packit b1f7ae
 * Copyright (c) 2013-2017, Intel Corporation
Packit b1f7ae
 *
Packit b1f7ae
 * Redistribution and use in source and binary forms, with or without
Packit b1f7ae
 * modification, are permitted provided that the following conditions are met:
Packit b1f7ae
 *
Packit b1f7ae
 *  * Redistributions of source code must retain the above copyright notice,
Packit b1f7ae
 *    this list of conditions and the following disclaimer.
Packit b1f7ae
 *  * Redistributions in binary form must reproduce the above copyright notice,
Packit b1f7ae
 *    this list of conditions and the following disclaimer in the documentation
Packit b1f7ae
 *    and/or other materials provided with the distribution.
Packit b1f7ae
 *  * Neither the name of Intel Corporation nor the names of its contributors
Packit b1f7ae
 *    may be used to endorse or promote products derived from this software
Packit b1f7ae
 *    without specific prior written permission.
Packit b1f7ae
 *
Packit b1f7ae
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit b1f7ae
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit b1f7ae
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit b1f7ae
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
Packit b1f7ae
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Packit b1f7ae
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Packit b1f7ae
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Packit b1f7ae
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Packit b1f7ae
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Packit b1f7ae
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Packit b1f7ae
 * POSSIBILITY OF SUCH DAMAGE.
Packit b1f7ae
 */
Packit b1f7ae
Packit b1f7ae
#ifndef PTUNIT_H
Packit b1f7ae
#define PTUNIT_H
Packit b1f7ae
Packit b1f7ae
#include <stdint.h>
Packit b1f7ae
#include <string.h>
Packit b1f7ae
Packit b1f7ae
#ifdef __cplusplus
Packit b1f7ae
extern "C" {
Packit b1f7ae
#endif
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* A source location for reporting unit test fails. */
Packit b1f7ae
struct ptunit_srcloc {
Packit b1f7ae
	/* The source file. */
Packit b1f7ae
	const char *file;
Packit b1f7ae
Packit b1f7ae
	/* The source line. */
Packit b1f7ae
	uint32_t line;
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
/* A unit test result type.
Packit b1f7ae
 *
Packit b1f7ae
 * This distinguishes the various potential results of a unit test.
Packit b1f7ae
 */
Packit b1f7ae
enum ptunit_result_type {
Packit b1f7ae
	/* The test has passed. */
Packit b1f7ae
	ptur_passed,
Packit b1f7ae
Packit b1f7ae
	/* The test has been skipped. */
Packit b1f7ae
	ptur_skipped,
Packit b1f7ae
Packit b1f7ae
	/* The test failed a signed/unsigned integer comparison. */
Packit b1f7ae
	ptur_failed_signed_int,
Packit b1f7ae
	ptur_failed_unsigned_int,
Packit b1f7ae
Packit b1f7ae
	/* The test failed a pointer comparison. */
Packit b1f7ae
	ptur_failed_pointer,
Packit b1f7ae
Packit b1f7ae
	/* The test failed a string comparison. */
Packit b1f7ae
	ptur_failed_str
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
/* A unit test result.
Packit b1f7ae
 *
Packit b1f7ae
 * We separate test execution and result reporting. A unit test function
Packit b1f7ae
 * returns a structured result that can later be used for reporting.
Packit b1f7ae
 */
Packit b1f7ae
struct ptunit_failed_signed_int {
Packit b1f7ae
	/* The expression that failed. */
Packit b1f7ae
	const char *expr;
Packit b1f7ae
Packit b1f7ae
	/* A string representation of the comparison operation. */
Packit b1f7ae
	const char *cmp;
Packit b1f7ae
Packit b1f7ae
	/* The expected value. */
Packit b1f7ae
	int64_t expected;
Packit b1f7ae
Packit b1f7ae
	/* The actual value. */
Packit b1f7ae
	int64_t actual;
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
struct ptunit_failed_unsigned_int {
Packit b1f7ae
	/* The expression that failed. */
Packit b1f7ae
	const char *expr;
Packit b1f7ae
Packit b1f7ae
	/* A string representation of the comparison operation. */
Packit b1f7ae
	const char *cmp;
Packit b1f7ae
Packit b1f7ae
	/* The expected value. */
Packit b1f7ae
	uint64_t expected;
Packit b1f7ae
Packit b1f7ae
	/* The actual value. */
Packit b1f7ae
	uint64_t actual;
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
struct ptunit_failed_pointer {
Packit b1f7ae
	/* The expression that failed. */
Packit b1f7ae
	const char *expr;
Packit b1f7ae
Packit b1f7ae
	/* A string representation of the comparison operation. */
Packit b1f7ae
	const char *cmp;
Packit b1f7ae
Packit b1f7ae
	/* The expected value. */
Packit b1f7ae
	const void *expected;
Packit b1f7ae
Packit b1f7ae
	/* The actual value. */
Packit b1f7ae
	const void *actual;
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
struct ptunit_failed_str {
Packit b1f7ae
	/* The expression that failed. */
Packit b1f7ae
	const char *expr;
Packit b1f7ae
Packit b1f7ae
	/* A string representation of the comparison operation. */
Packit b1f7ae
	const char *cmp;
Packit b1f7ae
Packit b1f7ae
	/* The expected value. */
Packit b1f7ae
	char *expected;
Packit b1f7ae
Packit b1f7ae
	/* The actual value. */
Packit b1f7ae
	char *actual;
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
struct ptunit_result {
Packit b1f7ae
	/* The test result type. */
Packit b1f7ae
	enum ptunit_result_type type;
Packit b1f7ae
Packit b1f7ae
	/* Test result details depending on the result type. */
Packit b1f7ae
	struct {
Packit b1f7ae
		/* The source location of the fail. */
Packit b1f7ae
		struct ptunit_srcloc where;
Packit b1f7ae
Packit b1f7ae
		union {
Packit b1f7ae
			struct ptunit_failed_signed_int signed_int;
Packit b1f7ae
			struct ptunit_failed_unsigned_int unsigned_int;
Packit b1f7ae
			struct ptunit_failed_pointer pointer;
Packit b1f7ae
			struct ptunit_failed_str str;
Packit b1f7ae
		} variant;
Packit b1f7ae
	} failed;
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
/* A unit test function. */
Packit b1f7ae
typedef struct ptunit_result (*ptunit_tfun_t)(void);
Packit b1f7ae
Packit b1f7ae
/* A unit test.
Packit b1f7ae
 *
Packit b1f7ae
 * This is used for logging and reporting.
Packit b1f7ae
 *
Packit b1f7ae
 * It is not used for running tests or even for storing tests to be run at a
Packit b1f7ae
 * later time.
Packit b1f7ae
 */
Packit b1f7ae
struct ptunit_test {
Packit b1f7ae
	/* The test name. */
Packit b1f7ae
	const char *name;
Packit b1f7ae
Packit b1f7ae
	/* The optional test arguments. */
Packit b1f7ae
	const char *args;
Packit b1f7ae
Packit b1f7ae
	/* The test result. */
Packit b1f7ae
	struct ptunit_result result;
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
/* A unit test suite.
Packit b1f7ae
 *
Packit b1f7ae
 * This is a simple summary of all tests that have been run.
Packit b1f7ae
 */
Packit b1f7ae
struct ptunit_suite {
Packit b1f7ae
	/* An optional suite name. */
Packit b1f7ae
	const char *name;
Packit b1f7ae
Packit b1f7ae
	/* The number of total tests. */
Packit b1f7ae
	uint32_t nr_tests;
Packit b1f7ae
Packit b1f7ae
	/* The number of tests that have been skipped. */
Packit b1f7ae
	uint32_t nr_skips;
Packit b1f7ae
Packit b1f7ae
	/* The number of tests that have failed. */
Packit b1f7ae
	uint32_t nr_fails;
Packit b1f7ae
};
Packit b1f7ae
Packit b1f7ae
/* Create a unit test source location. */
Packit b1f7ae
extern struct ptunit_srcloc ptunit_mk_srcloc(const char *file, uint32_t line);
Packit b1f7ae
Packit b1f7ae
#define ptu_here() ptunit_mk_srcloc(__FILE__, __LINE__)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Create unit test passed and not run results. */
Packit b1f7ae
extern struct ptunit_result ptunit_mk_passed(void);
Packit b1f7ae
extern struct ptunit_result ptunit_mk_skipped(void);
Packit b1f7ae
Packit b1f7ae
/* Create a unit test failed signed int result. */
Packit b1f7ae
extern struct ptunit_result ptunit_mk_failed_signed_int(const char *expr,
Packit b1f7ae
							const char *cmp,
Packit b1f7ae
							struct ptunit_srcloc,
Packit b1f7ae
							int64_t actual,
Packit b1f7ae
							int64_t expected);
Packit b1f7ae
Packit b1f7ae
#define ptunit_int_cmp(A, E, C)						\
Packit b1f7ae
	do {								\
Packit b1f7ae
		int64_t a = (A), e = (E);				\
Packit b1f7ae
									\
Packit b1f7ae
		if (!(a C e))						\
Packit b1f7ae
			return ptunit_mk_failed_signed_int(#A #C #E, #C, \
Packit b1f7ae
							   ptu_here(),	\
Packit b1f7ae
							   a, e);	\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Create a unit test failed unsigned int result. */
Packit b1f7ae
extern struct ptunit_result ptunit_mk_failed_unsigned_int(const char *expr,
Packit b1f7ae
							  const char *cmp,
Packit b1f7ae
							  struct ptunit_srcloc,
Packit b1f7ae
							  int64_t actual,
Packit b1f7ae
							  int64_t expected);
Packit b1f7ae
Packit b1f7ae
#define ptunit_uint_cmp(A, E, C)					\
Packit b1f7ae
	do {								\
Packit b1f7ae
		uint64_t a = (A), e = (E);				\
Packit b1f7ae
									\
Packit b1f7ae
		if (!(a C e))						\
Packit b1f7ae
			return ptunit_mk_failed_unsigned_int(#A #C #E, #C, \
Packit b1f7ae
							     ptu_here(), \
Packit b1f7ae
							     a, e);	\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Create a unit test failed pointer result. */
Packit b1f7ae
extern struct ptunit_result ptunit_mk_failed_pointer(const char *expr,
Packit b1f7ae
						     const char *cmp,
Packit b1f7ae
						     struct ptunit_srcloc,
Packit b1f7ae
						     const void *actual,
Packit b1f7ae
						     const void *expected);
Packit b1f7ae
Packit b1f7ae
#define ptunit_ptr_cmp(A, E, C)						\
Packit b1f7ae
	do {								\
Packit b1f7ae
		const void *a = (A), *e = (E);				\
Packit b1f7ae
									\
Packit b1f7ae
		if (!(a C e))						\
Packit b1f7ae
			return ptunit_mk_failed_pointer(#A #C #E, #C,	\
Packit b1f7ae
							ptu_here(),	\
Packit b1f7ae
							a, e);		\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Create a unit test failed string result. */
Packit b1f7ae
extern struct ptunit_result ptunit_mk_failed_str(const char *expr,
Packit b1f7ae
						 const char *cmp,
Packit b1f7ae
						 struct ptunit_srcloc,
Packit b1f7ae
						 const char *actual,
Packit b1f7ae
						 const char *expected);
Packit b1f7ae
Packit b1f7ae
#define ptunit_str_cmp(A, E, C)						\
Packit b1f7ae
	do {								\
Packit b1f7ae
		const char *a = (A), *e = (E);				\
Packit b1f7ae
									\
Packit b1f7ae
		if (!a || !e || !(strcmp(a, e) C 0))			\
Packit b1f7ae
			return ptunit_mk_failed_str(#A "~"#C #E, "~"#C,	\
Packit b1f7ae
						    ptu_here(),		\
Packit b1f7ae
						    a, e);		\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Run a sub-unit test; return on fail. */
Packit b1f7ae
Packit b1f7ae
#define ptunit_subtest(T, ...)				\
Packit b1f7ae
	do {						\
Packit b1f7ae
		struct ptunit_result result;		\
Packit b1f7ae
							\
Packit b1f7ae
		result = (T)(__VA_ARGS__);		\
Packit b1f7ae
		if (result.type != ptur_passed)		\
Packit b1f7ae
			return result;			\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Run a sub-unit test; return on fail from here. */
Packit b1f7ae
Packit b1f7ae
#define ptunit_check(T, ...)					\
Packit b1f7ae
	do {							\
Packit b1f7ae
		struct ptunit_result result;			\
Packit b1f7ae
								\
Packit b1f7ae
		result = (T)(__VA_ARGS__);			\
Packit b1f7ae
		if (result.type != ptur_passed) {		\
Packit b1f7ae
			result.failed.where = ptu_here();	\
Packit b1f7ae
			return result;				\
Packit b1f7ae
		}						\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Create a unit test. */
Packit b1f7ae
extern struct ptunit_test ptunit_mk_test(const char *name, const char *args);
Packit b1f7ae
Packit b1f7ae
/* Destroy a unit test. */
Packit b1f7ae
extern void ptunit_fini_test(struct ptunit_test *);
Packit b1f7ae
Packit b1f7ae
/* Create a unit test suite. */
Packit b1f7ae
extern struct ptunit_suite ptunit_mk_suite(int argc, char **argv);
Packit b1f7ae
Packit b1f7ae
/* Log a unit test result.
Packit b1f7ae
 *
Packit b1f7ae
 * This may also report test fails depending on the configuration.
Packit b1f7ae
 */
Packit b1f7ae
extern void ptunit_log_test(struct ptunit_suite *, const struct ptunit_test *);
Packit b1f7ae
Packit b1f7ae
/* Print a summary report for a unit test suite. */
Packit b1f7ae
extern void ptunit_report(const struct ptunit_suite *);
Packit b1f7ae
Packit b1f7ae
/* Run a single simple unit test and log its result. */
Packit b1f7ae
Packit b1f7ae
#define ptunit_run(S, T)				\
Packit b1f7ae
	do {						\
Packit b1f7ae
		struct ptunit_test test;		\
Packit b1f7ae
							\
Packit b1f7ae
		test = ptunit_mk_test(#T, NULL);	\
Packit b1f7ae
		test.result = (T)();			\
Packit b1f7ae
							\
Packit b1f7ae
		ptunit_log_test(S, &test);		\
Packit b1f7ae
		ptunit_fini_test(&test);		\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Run a single parameterized unit test and log its result. */
Packit b1f7ae
Packit b1f7ae
#define ptunit_run_p(S, T, ...)					\
Packit b1f7ae
	do {							\
Packit b1f7ae
		struct ptunit_test test;			\
Packit b1f7ae
								\
Packit b1f7ae
		test = ptunit_mk_test(#T, #__VA_ARGS__);	\
Packit b1f7ae
		test.result = (T)(__VA_ARGS__);			\
Packit b1f7ae
								\
Packit b1f7ae
		ptunit_log_test(S, &test);			\
Packit b1f7ae
		ptunit_fini_test(&test);			\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Run a single unit test with fixture and an explict argument list.
Packit b1f7ae
 *
Packit b1f7ae
 * The first argument in the argument list is typically the fixture.
Packit b1f7ae
 */
Packit b1f7ae
Packit b1f7ae
#define ptunit_frun(R, T, F, ...)				\
Packit b1f7ae
	do {							\
Packit b1f7ae
		struct ptunit_result *pr = &(R);		\
Packit b1f7ae
								\
Packit b1f7ae
		pr->type = ptur_passed;				\
Packit b1f7ae
		if ((F)->init)					\
Packit b1f7ae
			*pr = (F)->init(F);			\
Packit b1f7ae
								\
Packit b1f7ae
		if (pr->type == ptur_passed) {			\
Packit b1f7ae
			*pr = (T)(__VA_ARGS__);			\
Packit b1f7ae
								\
Packit b1f7ae
			if ((F)->fini) {			\
Packit b1f7ae
				if (pr->type == ptur_passed)	\
Packit b1f7ae
					*pr = (F)->fini(F);	\
Packit b1f7ae
				else				\
Packit b1f7ae
					(void) (F)->fini(F);	\
Packit b1f7ae
			}					\
Packit b1f7ae
		}						\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Run a single unit test with fixture and log its result. */
Packit b1f7ae
Packit b1f7ae
#define ptunit_run_f(S, T, F)					\
Packit b1f7ae
	do {							\
Packit b1f7ae
		struct ptunit_test test;			\
Packit b1f7ae
								\
Packit b1f7ae
		test = ptunit_mk_test(#T, #F);			\
Packit b1f7ae
								\
Packit b1f7ae
		ptunit_frun(test.result, T, &(F), &(F));	\
Packit b1f7ae
								\
Packit b1f7ae
		ptunit_log_test(S, &test);			\
Packit b1f7ae
		ptunit_fini_test(&test);			\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* Run a single parameterized unit test with fixture and log its result. */
Packit b1f7ae
Packit b1f7ae
#define ptunit_run_fp(S, T, F, ...)					\
Packit b1f7ae
	do {								\
Packit b1f7ae
		struct ptunit_test test;				\
Packit b1f7ae
									\
Packit b1f7ae
		test = ptunit_mk_test(#T, #F ", " #__VA_ARGS__);	\
Packit b1f7ae
									\
Packit b1f7ae
		ptunit_frun(test.result, T, &(F), &(F), __VA_ARGS__);	\
Packit b1f7ae
									\
Packit b1f7ae
		ptunit_log_test(S, &test);				\
Packit b1f7ae
		ptunit_fini_test(&test);				\
Packit b1f7ae
	} while (0)
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
Packit b1f7ae
/* The actual macros to be used in unit tests.
Packit b1f7ae
 *
Packit b1f7ae
 * Do not use the above ptunit_ macros directly.
Packit b1f7ae
 */
Packit b1f7ae
Packit b1f7ae
#define ptu_int_eq(A, E) ptunit_int_cmp(A, E, ==)
Packit b1f7ae
#define ptu_int_ne(A, E) ptunit_int_cmp(A, E, !=)
Packit b1f7ae
#define ptu_int_gt(A, E) ptunit_int_cmp(A, E, >)
Packit b1f7ae
#define ptu_int_ge(A, E) ptunit_int_cmp(A, E, >=)
Packit b1f7ae
#define ptu_int_lt(A, E) ptunit_int_cmp(A, E, <)
Packit b1f7ae
#define ptu_int_le(A, E) ptunit_int_cmp(A, E, <=)
Packit b1f7ae
Packit b1f7ae
#define ptu_uint_eq(A, E) ptunit_uint_cmp(A, E, ==)
Packit b1f7ae
#define ptu_uint_ne(A, E) ptunit_uint_cmp(A, E, !=)
Packit b1f7ae
#define ptu_uint_gt(A, E) ptunit_uint_cmp(A, E, >)
Packit b1f7ae
#define ptu_uint_ge(A, E) ptunit_uint_cmp(A, E, >=)
Packit b1f7ae
#define ptu_uint_lt(A, E) ptunit_uint_cmp(A, E, <)
Packit b1f7ae
#define ptu_uint_le(A, E) ptunit_uint_cmp(A, E, <=)
Packit b1f7ae
Packit b1f7ae
#define ptu_ptr_eq(A, E) ptunit_ptr_cmp(A, E, ==)
Packit b1f7ae
#define ptu_ptr_ne(A, E) ptunit_ptr_cmp(A, E, !=)
Packit b1f7ae
#define ptu_ptr_gt(A, E) ptunit_ptr_cmp(A, E, >)
Packit b1f7ae
#define ptu_ptr_ge(A, E) ptunit_ptr_cmp(A, E, >=)
Packit b1f7ae
#define ptu_ptr_lt(A, E) ptunit_ptr_cmp(A, E, <)
Packit b1f7ae
#define ptu_ptr_le(A, E) ptunit_ptr_cmp(A, E, <=)
Packit b1f7ae
#define ptu_null(A) ptunit_ptr_cmp(A, NULL, ==)
Packit b1f7ae
#define ptu_ptr(A) ptunit_ptr_cmp(A, NULL, !=)
Packit b1f7ae
Packit b1f7ae
#define ptu_str_eq(A, E) ptunit_str_cmp(A, E, ==)
Packit b1f7ae
#define ptu_str_ne(A, E) ptunit_str_cmp(A, E, !=)
Packit b1f7ae
Packit b1f7ae
/* Indicate that a unit test passed. */
Packit b1f7ae
#define ptu_passed() ptunit_mk_passed()
Packit b1f7ae
Packit b1f7ae
/* Skip a unit test. */
Packit b1f7ae
#define ptu_skipped() ptunit_mk_skipped()
Packit b1f7ae
Packit b1f7ae
/* Run a sub-unit test; return on fail. */
Packit b1f7ae
#define ptu_test(T, ...) ptunit_subtest(T, __VA_ARGS__)
Packit b1f7ae
Packit b1f7ae
/* Run a sub-unit test; return on fail from here. */
Packit b1f7ae
#define ptu_check(T, ...) ptunit_check(T, __VA_ARGS__)
Packit b1f7ae
Packit b1f7ae
/* Run a single unit test. */
Packit b1f7ae
#define ptu_run(S, T) ptunit_run(&(S), T)
Packit b1f7ae
Packit b1f7ae
/* Run a single parameterized unit test. */
Packit b1f7ae
#define ptu_run_p(S, T, ...) ptunit_run_p(&(S), T, __VA_ARGS__)
Packit b1f7ae
Packit b1f7ae
/* Run a single unit test with fixture. */
Packit b1f7ae
#define ptu_run_f(S, T, F) ptunit_run_f(&(S), T, F)
Packit b1f7ae
Packit b1f7ae
/* Run a single parameterized unit test with fixture. */
Packit b1f7ae
#define ptu_run_fp(S, T, F, ...) ptunit_run_fp(&(S), T, F, __VA_ARGS__)
Packit b1f7ae
Packit b1f7ae
#ifdef __cplusplus
Packit b1f7ae
}
Packit b1f7ae
#endif
Packit b1f7ae
Packit b1f7ae
#endif /* PTUNIT_H */