From 5dee4e56292fdf153d8f731997430da5e498f78d Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Fri, 11 Feb 2022 20:28:43 +0800 Subject: [PATCH 01/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0cmake=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 yonglin_zhang/CMakeLists.txt diff --git a/yonglin_zhang/CMakeLists.txt b/yonglin_zhang/CMakeLists.txt new file mode 100644 index 0000000..dc9b184 --- /dev/null +++ b/yonglin_zhang/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.0) + +project(alg C) + +add_subdirectory(unit-testing) +add_subdirectory(link_list) \ No newline at end of file -- Gitee From 1ad8f05867504b0d2cab40d2841c88dba50383e5 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Fri, 11 Feb 2022 20:40:02 +0800 Subject: [PATCH 02/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=B8=B8=E7=94=A8?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/include/alg_errno.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 yonglin_zhang/include/alg_errno.h diff --git a/yonglin_zhang/include/alg_errno.h b/yonglin_zhang/include/alg_errno.h new file mode 100644 index 0000000..df7372e --- /dev/null +++ b/yonglin_zhang/include/alg_errno.h @@ -0,0 +1,20 @@ +/** + * \brief 算法通用错误码 +*/ + +#ifndef ALG_ERRNO_H +#define ALG_ERRNO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define ALG_OK 0x0000 执行成功 +#define ALG_BAD_INPUT 0x0001 输入数据不合法 +#define ALG_MALLOC_FAIL 0x0002 内存空间不足 + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file -- Gitee From 332444ed4421b5385b128fbf9b41cd298eb6fb48 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Fri, 11 Feb 2022 20:50:35 +0800 Subject: [PATCH 03/34] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=A4=B4=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/include/check.h | 2366 +++++++++++++++++++++++++++++++++ 1 file changed, 2366 insertions(+) create mode 100644 yonglin_zhang/include/check.h diff --git a/yonglin_zhang/include/check.h b/yonglin_zhang/include/check.h new file mode 100644 index 0000000..497f0ea --- /dev/null +++ b/yonglin_zhang/include/check.h @@ -0,0 +1,2366 @@ +/*-*- mode:C; -*- */ +/* + * Check: a unit test framework for C + * Copyright (C) 2001, 2002 Arien Malec + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef CHECK_H +#define CHECK_H + +#include +#include +#include +#include + +#include + +/* + Macros and functions starting with _ (underscore) are internal and + may change without notice. You have been warned!. +*/ + + +#ifdef __cplusplus +#define CK_CPPSTART extern "C" { +#define CK_CPPEND } +CK_CPPSTART +#endif + +/** + * __GNUC_PATCHLEVEL__ is new to GCC 3.0; + * it is also present in the widely-used development snapshots leading up to 3.0 + * (which identify themselves as GCC 2.96 or 2.97, depending on which snapshot you have). + * + * https://stackoverflow.com/questions/1936719/what-are-the-gcc-predefined-macros-for-the-compilers-version-number/1936745#1936745 + */ + +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +#define GCC_VERSION_AT_LEAST(major, minor, patch) \ +((__GNUC__ > (major)) || \ + (__GNUC__ == (major) && __GNUC_MINOR__ > (minor)) || \ + (__GNUC__ == (major) && __GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patch)) ) +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) +#define GCC_VERSION_AT_LEAST(major, minor, patch) \ +((__GNUC__ > (major)) || \ + (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) +#else +#define GCC_VERSION_AT_LEAST(major, minor, patch) 0 +#endif + +#if GCC_VERSION_AT_LEAST(2,95,3) +#define CK_ATTRIBUTE_UNUSED __attribute__ ((unused)) +#define CK_ATTRIBUTE_FORMAT(a, b, c) __attribute__ ((format (a, b, c))) +#else +#define CK_ATTRIBUTE_UNUSED +#define CK_ATTRIBUTE_FORMAT(a, b, c) +#endif /* GCC 2.95 */ + +#if GCC_VERSION_AT_LEAST(2,5,0) +#define CK_ATTRIBUTE_NORETURN __attribute__ ((noreturn)) +#else +#define CK_ATTRIBUTE_NORETURN +#endif /* GCC 2.5 */ + +#if GCC_VERSION_AT_LEAST(4,7,4) && (__STDC_VERSION__ >= 199901L) +/* Operator _Pragma introduced in C99 */ +#define CK_DIAGNOSTIC_STRINGIFY(x) #x +#define CK_DIAGNOSTIC_HELPER1(y) CK_DIAGNOSTIC_STRINGIFY(GCC diagnostic ignored y) +#define CK_DIAGNOSTIC_HELPER2(z) CK_DIAGNOSTIC_HELPER1(#z) +#define CK_DIAGNOSTIC_PUSH_IGNORE(w) \ + _Pragma("GCC diagnostic push") \ + _Pragma(CK_DIAGNOSTIC_HELPER2(w)) +#define CK_DIAGNOSTIC_POP(w) _Pragma ("GCC diagnostic pop") +#else +#define CK_DIAGNOSTIC_PUSH_IGNORE(w) +#define CK_DIAGNOSTIC_POP(w) +#endif /* GCC 4.7.4 */ + +#undef GCC_VERSION_AT_LEAST + +#include + +#if defined(_MSC_VER) +/* define pid_t for Windows, as it is needed later */ +#define pid_t int +#endif /* _MSC_VER */ + +/* + * Used to create the linker script for hiding lib-local symbols. Shall + * be put directly in front of the exported symbol. + */ +#define CK_EXPORT + +/* + * Used for MSVC to create the export attribute + * CK_DLL_EXP is defined during the compilation of the library + * on the command line. + * + * This definition is only used when building or linking to + * the shared library, i.e. libcheck.so. When building the library + * the value must be "_declspec(dllexport)". + * When linking with the library, the value must be "_declspec(dllimport)" + * + * This is only used with Microsoft Visual C. In other systems + * the value is empty. In MSVC the value is empty when linking with + * a static library. + */ +#ifndef CK_DLL_EXP +#define CK_DLL_EXP +#endif + +/* check version numbers */ + +#define CHECK_MAJOR_VERSION (0) +#define CHECK_MINOR_VERSION (15) +#define CHECK_MICRO_VERSION (2) + +CK_DLL_EXP extern int CK_EXPORT check_major_version; +CK_DLL_EXP extern int CK_EXPORT check_minor_version; +CK_DLL_EXP extern int CK_EXPORT check_micro_version; + +#ifndef NULL +#define NULL ((void*)0) +#endif + +/** + * Type for a test case + * + * A TCase represents a test case. Create with tcase_create, free + * with tcase_free. For the moment, test cases can only be run + * through a suite +*/ +typedef struct TCase TCase; + +/** + * Type for a test function + */ +typedef void (*TFun) (int); + +/** + * Type for a setup/teardown function + */ +typedef void (*SFun) (void); + +/** + * Type for a test suite + */ +typedef struct Suite Suite; + +/** + * Type for a test, which wraps a test function + */ +typedef struct TTest { + const char *name; + TFun fn; + const char *file; + int line; +} TTest; + +/** + * Creates a test suite with the given name. + * + * Create a suite, which will contain test cases. Once + * created, use suite_add_tcase() to add test cases. + * When finished, create a suite runner from the + * suite using srunner_create() + * + * @param name name of the suite + * + * @return suite + * + * @since 0.6.0 + */ +CK_DLL_EXP Suite *CK_EXPORT suite_create(const char *name); + +/** + * Determines whether a given test suite contains a case named after a + * given string. + * + * @param s suite to check + * @param tcname test case to look for + * + * @return 1 iff the given test case is within the given suite; + * 0 otherwise + * + * @since 0.9.9 + */ +CK_DLL_EXP int CK_EXPORT suite_tcase(Suite * s, const char *tcname); + +/** + * Add a test case to a suite. + * + * Note that if the TCase has already been added attempting + * to add it again will be ignored. + * + * @param s suite to add test case to + * @param tc test case to add to suite + * + * @since 0.6.0 + */ +CK_DLL_EXP void CK_EXPORT suite_add_tcase(Suite * s, TCase * tc); + +/** + * Create a test case. + * + * Once created, tests can be added with the tcase_add_test() + * function, and the test case assigned to a suite with the + * suite_add_tcase() function. + * + * @param name name of the test case + * + * @return test case containing no tests + * + * @since 0.6.0 + * */ +CK_DLL_EXP TCase *CK_EXPORT tcase_create(const char *name); + +/** + * Associate a test case with certain tags. + * Replaces any existing tags with the new set. + * + * @param tc the test case + * + * @param tags string containing arbitrary tags separated by spaces. + * This will be copied. Passing NULL clears all tags. + * + * @since 0.11.0 + * */ +CK_DLL_EXP void CK_EXPORT tcase_set_tags(TCase * tc, + const char *tags); +/** + * Add a test function to a test case + * + * @param tc test case to add test to + * @param tf test function to add to test case + * + * @since 0.6.0 + * */ +#define tcase_add_test(tc,tf) tcase_add_test_raise_signal(tc,tf,0) + +/** + * Add a test function with signal handling to a test case + * + * The added test is expected to terminate by throwing the given signal + * + * @param tc test case to add test to + * @param tf test function to add to test case + * @param signal expected signal for test function to throw in order for + * the test to be considered passing + * + * @since 0.9.2 + * */ +#define tcase_add_test_raise_signal(tc,ttest,signal) \ + _tcase_add_test((tc),(ttest),(signal), 0, 0, 1) + +/** + * Add a test function with an expected exit value to a test case + * + * The added test is expected to terminate by exiting with the given value + * + * @param tc test case to add test to + * @param tf test function to add to test case + * @param expected_exit_value exit value for test function to return in + * order for the test to be considered passing + * + * @since 0.9.7 + */ +#define tcase_add_exit_test(tc, ttest, expected_exit_value) \ + _tcase_add_test((tc),(ttest),0,(expected_exit_value),0,1) + +/** + * Add a looping test function to a test case + * + * The test will be called in a for(i = s; i < e; i++) loop with each + * iteration being executed in a new context. The loop variable 'i' is + * available in the test. + * + * @param tc test case to add test to + * @param tf function to add to test case + * @param s starting index for value "i" in test + * @param e ending index for value "i" in test + * + * @since 0.9.4 + */ +#define tcase_add_loop_test(tc,ttest,s,e) \ + _tcase_add_test((tc),(ttest),0,0,(s),(e)) + +/** + * Add a looping test function with signal handling to a test case + * + * The test will be called in a for(i = s; i < e; i++) loop with each + * iteration being executed in a new context. The loop variable 'i' is + * available in the test. + * + * The added test is expected to terminate by throwing the given signal + * + * @param tc test case to add test to + * @param tf function to add to test case + * @param signal expected signal for test function to throw in order for + * the test to be considered passing + * @param s starting index for value "i" in test + * @param e ending index for value "i" in test + * + * @since 0.9.5 + */ +#define tcase_add_loop_test_raise_signal(tc,ttest,signal,s,e) \ + _tcase_add_test((tc),(ttest),(signal),0,(s),(e)) + +/** + * Add a looping test function with an expected exit value to a test case + * + * The test will be called in a for(i = s; i < e; i++) loop with each + * iteration being executed in a new context. The loop variable 'i' is + * available in the test. + * + * The added test is expected to terminate by exiting with the given value + * + * @param tc test case to add test to + * @param tf function to add to test case + * @param expected_exit_value exit value for test function to return in + * order for the test to be considered passing + * @param s starting index for value "i" in test + * @param e ending index for value "i" in test + * + * @since 0.9.7 + */ +#define tcase_add_loop_exit_test(tc,ttest,expected_exit_value,s,e) \ + _tcase_add_test((tc),(ttest),0,(expected_exit_value),(s),(e)) + +/* Add a test function to a test case + (function version -- use this when the macro won't work +*/ +CK_DLL_EXP void CK_EXPORT _tcase_add_test(TCase * tc, const TTest * ttest, + int _signal, int allowed_exit_value, + int start, int end); + +/** + * Add unchecked fixture setup/teardown functions to a test case + * + * Unchecked fixture functions are run at the start and end of the + * test case, and not before and after unit tests. Further, + * unchecked fixture functions are not run in a separate address space, + * like test functions, and so must not exit or signal (e.g., + * segfault). + * + * Also, when run in CK_NOFORK mode, unchecked fixture functions may + * lead to different unit test behavior if unit tests change data + * setup by the fixture functions. + * + * Note that if a setup function fails, the remaining setup functions + * will be omitted, as will the test case and the teardown functions. + * If a teardown function fails the remaining teardown functins will be + * omitted. + * + * @param tc test case to add unchecked fixture setup/teardown to + * @param setup function to add to be executed before the test case; + * if NULL no setup function is added + * @param teardown function to add to be executed after the test case; + * if NULL no teardown function is added + * @since 0.8.0 + */ +CK_DLL_EXP void CK_EXPORT tcase_add_unchecked_fixture(TCase * tc, SFun setup, + SFun teardown); + +/** + * Add checked fixture setup/teardown functions to a test case + * + * Checked fixture functions are run before and after each unit test inside + * of the address space of the test. Thus, if using CK_FORK + * mode the separate process running the unit test will survive signals + * or unexpected exits in the fixture function. Also, if the setup + * function is idempotent, unit test behavior will be the same in + * CK_FORK and CK_NOFORK modes. + * + * However, since fixture functions are run before and after each unit + * test, they should not be expensive code. + * + * Note that if a setup function fails, the remaining setup functions + * will be omitted, as will the test and the teardown functions. If a + * teardown function fails the remaining teardown functins will be + * omitted. + * + * @param tc test case to add checked fixture setup/teardown to + * @param setup function to add to be executed before each unit test in + * the test case; if NULL no setup function is added + * @param teardown function to add to be executed after each unit test in + * the test case; if NULL no teardown function is added + * + * @since 0.8.0 +*/ +CK_DLL_EXP void CK_EXPORT tcase_add_checked_fixture(TCase * tc, SFun setup, + SFun teardown); + +/** + * Set the timeout for all tests in a test case. + * + * A test that lasts longer than the timeout (in seconds) will be killed + * and thus fail with an error. + * + * If not set, the default timeout is one assigned at compile time. If + * the environment variable CK_DEFAULT_TIMEOUT is defined and no timeout + * is set, the value in the environment variable is used. + * + * If Check is compile without fork() support this call is ignored, + * as timeouts are not possible. + * + * @param tc test case to assign timeout to + * @param timeout to use, in seconds. If the value contains a decimal + * portion, but no high resolution timer is available, + * the value is rounded up to the nearest second. + * + * @since 0.9.2 + */ +CK_DLL_EXP void CK_EXPORT tcase_set_timeout(TCase * tc, double timeout); + +/* Internal function to mark the start of a test function */ +CK_DLL_EXP void CK_EXPORT tcase_fn_start(const char *fname, const char *file, + int line); + +/** + * Retreive the name of the current running test. This is the name + * of the test passed to START_TEST. This is only valid when called + * from a running test. The value return outside of a running test is + * undefined. + * + * @since 0.11.0 + */ +CK_DLL_EXP const char* CK_EXPORT tcase_name(void); + +/** + * Start a unit test with START_TEST(unit_name), end with END_TEST. + * + * One must use braces within a START_/END_ pair to declare new variables + * + * @since 0.6.0 + */ +#define START_TEST(__testname)\ +static void __testname ## _fn (int _i CK_ATTRIBUTE_UNUSED);\ +static const TTest __testname ## _ttest = {""# __testname, __testname ## _fn, __FILE__, __LINE__};\ +static const TTest * __testname = & __testname ## _ttest;\ +static void __testname ## _fn (int _i CK_ATTRIBUTE_UNUSED) + +/** + * End a unit test + * + * @since 0.6.0 + */ +#define END_TEST + +/* + * Fail the test case unless expr is false + * + * This call is deprecated. + */ +#define fail_unless(expr, ...) \ + (expr) ? \ + _mark_point(__FILE__, __LINE__) : \ + _ck_assert_failed(__FILE__, __LINE__, "Assertion '"#expr"' failed" , ## __VA_ARGS__, NULL) + +/* + * Fail the test case if expr is false + * + * This call is deprecated. + * + * NOTE: The space before the comma sign before ## is essential to be compatible + * with gcc 2.95.3 and earlier. + * FIXME: these macros may conflict with C89 if expr is + * FIXME: strcmp (str1, str2) due to excessive string length. + */ +#define fail_if(expr, ...)\ + (expr) ? \ + _ck_assert_failed(__FILE__, __LINE__, "Failure '"#expr"' occurred" , ## __VA_ARGS__, NULL) \ + : _mark_point(__FILE__, __LINE__) + +/* + * Fail the test + * + * This call is deprecated. + */ +#define fail(...) _ck_assert_failed(__FILE__, __LINE__, "Failed" , ## __VA_ARGS__, NULL) + +/* + * This is called whenever an assertion fails. + * Note that it only has the noreturn modifier when + * using fork. If fork is unavailable, the function + * calls longjmp() when a test assertion fails. Marking + * the function as noreturn causes gcc to make assumptions + * which are not valid, as longjmp() is like a return. + */ +#if 0 +CK_DLL_EXP void CK_EXPORT _ck_assert_failed(const char *file, int line, + const char *expr, const char *msg, + ...) CK_ATTRIBUTE_NORETURN CK_ATTRIBUTE_FORMAT(printf, 4, 5); +#else +CK_DLL_EXP void CK_EXPORT _ck_assert_failed(const char *file, int line, + const char *expr, const char *msg, + ...) CK_ATTRIBUTE_FORMAT(printf, 4, 5); +#endif + +/** + * Fail the test if expression is false + * + * @param expr expression to evaluate + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.6 + */ +#define ck_assert(expr) ck_assert_msg(expr, NULL) + +/* The space before the comma sign before ## is essential to be compatible + with gcc 2.95.3 and earlier. +*/ +/** + * Fail the test if the expression is false; print message on failure + * + * @param expr expression to evaluate + * @param ... message to print (in printf format) if expression is false + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.6 + */ +#define ck_assert_msg(expr, ...) \ + (expr) ? \ + _mark_point(__FILE__, __LINE__) : \ + _ck_assert_failed(__FILE__, __LINE__, "Assertion '"#expr"' failed" , ## __VA_ARGS__) + +/** + * Unconditionally fail the test + * + * @note Once called, the remaining of the test is aborted + * + * @since 0.9.6 + */ +#define ck_abort() ck_abort_msg(NULL) +/** + * Unconditionally fail the test; print a message + * + * @param ... message to print (in printf format) + * + * @note Once called, the remaining of the test is aborted + * + * @since 0.9.6 + */ +#define ck_abort_msg(...) _ck_assert_failed(__FILE__, __LINE__, "Failed" , ## __VA_ARGS__) + +/* Signed and unsigned integer comparison macros with improved output compared to ck_assert(). */ +/* OP may be any comparison operator. */ +#define _ck_assert_int(X, OP, Y) do { \ + intmax_t _ck_x = (X); \ + intmax_t _ck_y = (Y); \ + ck_assert_msg(_ck_x OP _ck_y, "Assertion '%s' failed: %s == %jd, %s == %jd", #X" "#OP" "#Y, #X, _ck_x, #Y, _ck_y); \ +} while (0) + +/** + * Check two signed integers to determine if X==Y + * + * If not X==Y, the test fails. + * + * @param X signed integer + * @param Y signed integer to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.6 + */ +#define ck_assert_int_eq(X, Y) _ck_assert_int(X, ==, Y) +/** + * Check two signed integers to determine if X!=Y + * + * If not X!=Y, the test fails. + * + * @param X signed integer + * @param Y signed integer to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.6 + */ +#define ck_assert_int_ne(X, Y) _ck_assert_int(X, !=, Y) +/** + * Check two signed integers to determine if XY + * + * If not X>Y, the test fails. + * + * @param X signed integer + * @param Y signed integer to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.10 + */ +#define ck_assert_int_gt(X, Y) _ck_assert_int(X, >, Y) +/** + * Check two signed integers to determine if X>=Y + * + * If not X>=Y, the test fails. + * + * @param X signed integer + * @param Y signed integer to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.10 + */ +#define ck_assert_int_ge(X, Y) _ck_assert_int(X, >=, Y) + +#define _ck_assert_uint(X, OP, Y) do { \ + uintmax_t _ck_x = (X); \ + uintmax_t _ck_y = (Y); \ + ck_assert_msg(_ck_x OP _ck_y, "Assertion '%s' failed: %s == %ju, %s == %ju", #X" "#OP" "#Y, #X, _ck_x, #Y, _ck_y); \ +} while (0) +/** + * Check two unsigned integers to determine if X==Y + * + * If not X==Y, the test fails. + * + * @param X signed integer + * @param Y signed integer to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.10 + */ +#define ck_assert_uint_eq(X, Y) _ck_assert_uint(X, ==, Y) +/** + * Check two unsigned integers to determine if X!=Y + * + * If not X!=Y, the test fails. + * + * @param X signed integer + * @param Y signed integer to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.10 + */ +#define ck_assert_uint_ne(X, Y) _ck_assert_uint(X, !=, Y) +/** + * Check two unsigned integers to determine if XY + * + * If not X>Y, the test fails. + * + * @param X signed integer + * @param Y signed integer to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.10 + */ +#define ck_assert_uint_gt(X, Y) _ck_assert_uint(X, >, Y) +/** + * Check two unsigned integers to determine if X>=Y + * + * If not X>=Y, the test fails. + * + * @param X signed integer + * @param Y signed integer to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.10 + */ +#define ck_assert_uint_ge(X, Y) _ck_assert_uint(X, >=, Y) + +/* Number of digits after the decimal point to output via printf */ +#ifndef CK_FLOATING_DIG +# define CK_FLOATING_DIG 6 +#endif /* CK_FLOATING_DIG */ + +/* Floating point number comparison macros with improved output + * compared to ck_assert(). */ +/* OP may be any comparison operator, TP is type, TM is type modifier. */ +#define _ck_assert_floating(X, OP, Y, TP, TM) do { \ + TP _ck_x = (X); \ + TP _ck_y = (Y); \ + ck_assert_msg(_ck_x OP _ck_y, \ + "Assertion '%s' failed: %s == %.*" TM "g, %s == %.*" TM "g", \ + #X" "#OP" "#Y, \ + #X, (int)CK_FLOATING_DIG, _ck_x, \ + #Y, (int)CK_FLOATING_DIG, _ck_y); \ +} while (0) + +/* Check floating point number is finise. */ +/* TP is type, TM is type modifier. */ +#define _ck_assert_floating_finite(X, TP, TM) \ +do { \ + TP _ck_x = (X); \ + ck_assert_msg(isfinite(_ck_x), \ + "Assertion '%s' failed: %s == %.*" TM "g", \ + #X" is finite", \ + #X, (int)CK_FLOATING_DIG, _ck_x); \ +} while (0) + +/* Check floating point number is infinise. */ +/* TP is type, TM is type modifier. */ +#define _ck_assert_floating_infinite(X, TP, TM) \ +do { \ + TP _ck_x = (X); \ + ck_assert_msg(isinf(_ck_x), \ + "Assertion '%s' failed: %s == %.*" TM "g", \ + #X" is infinite", \ + #X, (int)CK_FLOATING_DIG, _ck_x); \ +} while (0) + +/* Check floating point number is "Not a Number". */ +/* TP is type, TM is type modifier. */ +#define _ck_assert_floating_nan(X, TP, TM) \ +do { \ + TP _ck_x = (X); \ + ck_assert_msg(isnan(_ck_x), \ + "Assertion '%s' failed: %s == %.*" TM "g", \ + #X" is NaN", \ + #X, (int)CK_FLOATING_DIG, _ck_x); \ +} while (0) + +/* Check floating point number is not "Not a Number". */ +/* TP is type, TM is type modifier. */ +#define _ck_assert_floating_nonnan(X, TP, TM) \ +do { \ + TP _ck_x = (X); \ + ck_assert_msg(!isnan(_ck_x), \ + "Assertion '%s' failed: %s == %.*" TM "g", \ + #X" is not NaN", \ + #X, (int)CK_FLOATING_DIG, _ck_x); \ +} while (0) + +/* Floating point tolerance comparison macros with improved output + * compared to ck_assert(). */ +/* OP, D can have values: >, -1; <, 1. */ +#define _ck_assert_floating_op_tol(X, OP, Y, T, D, TP, TM) do { \ + TP _ck_x = (X); \ + TP _ck_y = (Y); \ + TP _ck_t = (T); \ + ck_assert_msg((_ck_x - _ck_y) OP _ck_t * (D), \ + "Assertion '%s' failed: %s == %.*" TM "g, %s == %.*" TM "g, %s == %.*" TM "g", \ + #X" "#OP"= "#Y", error < "#T, \ + #X, (int)CK_FLOATING_DIG, _ck_x, \ + #Y, (int)CK_FLOATING_DIG, _ck_y, \ + #T, (int)CK_FLOATING_DIG, _ck_t); \ +} while (0) + +/* Floating point tolerance comparison macros with improved output + * compared to ck_assert(). */ +/* OP can have values: <; >=. */ +#define _ck_assert_floating_absdiff_op_tol(X, Y, OP, T, TP, TM) \ +do { \ + TP _ck_x = (X); \ + TP _ck_y = (Y); \ + TP _ck_t = (T); \ + ck_assert_msg(fabsl(_ck_y - _ck_x) OP _ck_t, \ + "Assertion '%s' failed: %s == %.*" TM "g, %s == %.*" TM "g, %s == %.*" TM "g", \ + "fabsl("#Y" - "#X") "#OP" "#T, \ + #X, (int)CK_FLOATING_DIG, _ck_x, \ + #Y, (int)CK_FLOATING_DIG, _ck_y, \ + #T, (int)CK_FLOATING_DIG, _ck_t); \ +} while (0) + +/** + * Check two single precision floating point numbers to determine if X == Y. + * + * Note that the usefulness of this assertion is very limited. If you + * want to compare two floating point numbers for equality, you probably + * want to use ck_assert_float_eq_tol instead. + * + * If not X == Y, the test fails. + * + * @param X floating point number (float) + * @param Y floating point number (float) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_eq(X, Y) _ck_assert_floating(X, ==, Y, float, "") +/** + * Check two single precision floating point numbers to determine if X != Y. + * + * Note that the usefulness of this assertion is very limited. If you + * want to compare two floating point numbers for equality, you probably + * want to use ck_assert_float_ne_tol instead. + * + * If not X != Y, the test fails. + * + * @param X floating point number (float) + * @param Y floating point number (float) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_ne(X, Y) _ck_assert_floating(X, !=, Y, float, "") +/** + * Check two single precision floating point numbers to determine if X < Y + * + * If not X < Y, the test fails. + * + * @param X floating point number (float) + * @param Y floating point number (float) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_lt(X, Y) _ck_assert_floating(X, <, Y, float, "") +/** + * Check two single precision floating point numbers to determine if X <= Y + * + * If not X <= Y, the test fails. + * + * @param X floating point number (float) + * @param Y floating point number (float) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_le(X, Y) _ck_assert_floating(X, <=, Y, float, "") +/** + * Check two single precision floating point numbers to determine if X > Y + * + * If not X > Y, the test fails. + * + * @param X floating point number (float) + * @param Y floating point number (float) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_gt(X, Y) _ck_assert_floating(X, >, Y, float, "") +/** + * Check two single precision floating point numbers to determine if X >= Y + * + * If not X >= Y, the test fails. + * + * @param X floating point number (float) + * @param Y floating point number (float) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_ge(X, Y) _ck_assert_floating(X, >=, Y, float, "") + +/** + * Check two single precision floating point numbers to determine if X≈Y + * with specified tolerance + * + * If not X ≈ Y with error < T, the test fails. + * + * @param X floating point number (float) + * @param Y floating point number (float) to compare against X + * @param T tolerance (float) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_eq_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, <, T, float, "") + +/** + * Check two single precision floating point numbers to determine if not X≈Y + * with specified tolerance + * + * If X ≈ Y with error < T, the test fails. + * + * @param X floating point number (float) + * @param Y floating point number (float) to compare against X + * @param T tolerance (float) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_ne_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, >=, T, float, "") + +/** + * Check two single precision floating point numbers to determine if X>≈Y + * with specified tolerance + * + * If not X >≈ Y with error < T, the test fails. + * + * @param X floating point number (float) + * @param Y floating point number (float) to compare against X + * @param T tolerance (float) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_ge_tol(X, Y, T) _ck_assert_floating_op_tol(X, >, Y, T, -1, float, "") + +/** + * Check two single precision floating point numbers to determine if X<≈Y + * with specified tolerance + * + * If not X <≈ Y with error < T, the test fails. + * + * @param X floating point number (float) + * @param Y floating point number (float) to compare against X + * @param T tolerance (float) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_le_tol(X, Y, T) _ck_assert_floating_op_tol(X, <, Y, T, 1, float, "") + +/** + * Check that a single precision floating point number is finite; i.e. is + * not +infinity, -infinity, or "Not a Number" (NaN) + * + * If X is +INFINITY or X is -INFINITY, or X is NaN, the test fails. + * + * @param X floating point number (float) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_finite(X) _ck_assert_floating_finite(X, float, "") + +/** + * Check that a single precision floating point number is infinite, + * either +infinity or -infinity + * + * If X is not +INFINITY and X is not -INFINITY, the test fails. + * + * @param X floating point number (float) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_infinite(X) _ck_assert_floating_infinite(X, float, "") + +/** + * Check that a single precision floating point number + * is "Not a Number" (NaN) + * + * If X is not NaN, the test fails. + * + * @param X floating point number (float) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_nan(X) _ck_assert_floating_nan(X, float, "") + +/** + * Check that a single precision floating point number is + * not "Not a Number" (NaN) + * + * If X is NaN, the test fails. + * + * @param X floating point number (float) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_float_nonnan(X) _ck_assert_floating_nonnan(X, float, "") + +/** + * Check two double precision floating point numbers to determine if X == Y. + * + * Note that the usefulness of this assertion is very limited. If you + * want to compare two floating point numbers for equality, you probably + * want to use ck_assert_double_eq_tol instead. + * + * If not X == Y, the test fails. + * + * @param X floating point number (double) + * @param Y floating point number (double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_eq(X, Y) _ck_assert_floating(X, ==, Y, double, "") +/** + * Check two double precision floating point numbers to determine if X != Y. + * + * Note that the usefulness of this assertion is very limited. If you + * want to compare two floating point numbers for equality, you probably + * want to use ck_assert_double_ne_tol instead. + * + * If not X != Y, the test fails. + * + * @param X floating point number (double) + * @param Y floating point number (double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_ne(X, Y) _ck_assert_floating(X, !=, Y, double, "") +/** + * Check two double precision floating point numbers to determine if X < Y + * + * If not X < Y, the test fails. + * + * @param X floating point number (double) + * @param Y floating point number (double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_lt(X, Y) _ck_assert_floating(X, <, Y, double, "") +/** + * Check two double precision floating point numbers to determine if X <= Y + * + * If not X <= Y, the test fails. + * + * @param X floating point number (double) + * @param Y floating point number (double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_le(X, Y) _ck_assert_floating(X, <=, Y, double, "") +/** + * Check two double precision floating point numbers to determine if X > Y + * + * If not X > Y, the test fails. + * + * @param X floating point number (double) + * @param Y floating point number (double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_gt(X, Y) _ck_assert_floating(X, >, Y, double, "") +/** + * Check two double precision floating point numbers to determine if X >= Y + * + * If not X >= Y, the test fails. + * + * @param X floating point number (double) + * @param Y floating point number (double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_ge(X, Y) _ck_assert_floating(X, >=, Y, double, "") + +/** + * Check two double precision floating point numbers to determine if X≈Y + * with specified tolerance + * + * If not X ≈ Y with error < T, the test fails. + * + * @param X floating point number (double) + * @param Y floating point number (double) to compare against X + * @param T tolerance (double) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_eq_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, <, T, double, "") + +/** + * Check two double precision floating point numbers to determine if not X≈Y + * with specified tolerance + * + * If X ≈ Y with error < T, the test fails. + * + * @param X floating point number (double) + * @param Y floating point number (double) to compare against X + * @param T tolerance (double) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_ne_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, >=, T, double, "") + +/** + * Check two double precision floating point numbers to determine if X>≈Y + * with specified tolerance + * + * If not X >≈ Y with error < T, the test fails. + * + * @param X floating point number (double) + * @param Y floating point number (double) to compare against X + * @param T tolerance (double) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_ge_tol(X, Y, T) _ck_assert_floating_op_tol(X, >, Y, T, -1, double, "") + +/** + * Check two double precision floating point numbers to determine if X<≈Y + * with specified tolerance + * + * If not X <≈ Y with error < T, the test fails. + * + * @param X floating point number (double) + * @param Y floating point number (double) to compare against X + * @param T tolerance (double) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_le_tol(X, Y, T) _ck_assert_floating_op_tol(X, <, Y, T, 1, double, "") + +/** + * Check that a double precision floating point number is finite; i.e. is + * not +infinity, -infinity, or "Not a Number" (NaN) + * + * If X is +INFINITY or X is -INFINITY, or X is NaN, the test fails. + * + * @param X floating point number (double) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_finite(X) _ck_assert_floating_finite(X, double, "") + +/** + * Check that a double precision floating point number is infinite, + * either +infinity or -infinity + * + * If X is not +INFINITY and X is not -INFINITY, the test fails. + * + * @param X floating point number (double) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_infinite(X) _ck_assert_floating_infinite(X, double, "") + +/** + * Check that a double precision floating point number + * is "Not a Number" (NaN) + * + * If X is not NaN, the test fails. + * + * @param X floating point number (double) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_nan(X) _ck_assert_floating_nan(X, double, "") + +/** + * Check that a double precision floating point number is + * not "Not a Number" (NaN) + * + * If X is NaN, the test fails. + * + * @param X floating point number (double) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_double_nonnan(X) _ck_assert_floating_nonnan(X, double, "") + +/** + * Check two double precision floating point numbers to determine if X == Y. + * + * Note that the usefulness of this assertion is very limited. If you + * want to compare two floating point numbers for equality, you probably + * want to use ck_assert_ldouble_eq_tol instead. + * + * If not X == Y, the test fails. + * + * @param X floating point number (long double) + * @param Y floating point number (long double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_eq(X, Y) _ck_assert_floating(X, ==, Y, long double, "L") +/** + * Check two double precision floating point numbers to determine if X != Y. + * + * Note that the usefulness of this assertion is very limited. If you + * want to compare two floating point numbers for equality, you probably + * want to use ck_assert_ldouble_ne_tol instead. + * + * If not X != Y, the test fails. + * + * @param X floating point number (long double) + * @param Y floating point number (long double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_ne(X, Y) _ck_assert_floating(X, !=, Y, long double, "L") +/** + * Check two double precision floating point numbers to determine if X < Y + * + * If not X < Y, the test fails. + * + * @param X floating point number (long double) + * @param Y floating point number (long double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_lt(X, Y) _ck_assert_floating(X, <, Y, long double, "L") +/** + * Check two double precision floating point numbers to determine if X <= Y + * + * If not X <= Y, the test fails. + * + * @param X floating point number (long double) + * @param Y floating point number (long double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_le(X, Y) _ck_assert_floating(X, <=, Y, long double, "L") +/** + * Check two double precision floating point numbers to determine if X > Y + * + * If not X > Y, the test fails. + * + * @param X floating point number (long double) + * @param Y floating point number (long double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_gt(X, Y) _ck_assert_floating(X, >, Y, long double, "L") +/** + * Check two double precision floating point numbers to determine if X >= Y + * + * If not X >= Y, the test fails. + * + * @param X floating point number (long double) + * @param Y floating point number (long double) to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_ge(X, Y) _ck_assert_floating(X, >=, Y, long double, "L") + +/** + * Check two double precision floating point numbers to determine if X≈Y + * with specified tolerance + * + * If not X ≈ Y with error < T, the test fails. + * + * @param X floating point number (long double) + * @param Y floating point number (long double) to compare against X + * @param T tolerance (long double) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_eq_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, <, T, long double, "L") + +/** + * Check two double precision floating point numbers to determine if not X≈Y + * with specified tolerance + * + * If X ≈ Y with error < T, the test fails. + * + * @param X floating point number (long double) + * @param Y floating point number (long double) to compare against X + * @param T tolerance (long double) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_ne_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, >=, T, long double, "L") + +/** + * Check two double precision floating point numbers to determine if X>≈Y + * with specified tolerance + * + * If not X >≈ Y with error < T, the test fails. + * + * @param X floating point number (long double) + * @param Y floating point number (long double) to compare against X + * @param T tolerance (long double) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_ge_tol(X, Y, T) _ck_assert_floating_op_tol(X, >, Y, T, -1, long double, "L") + +/** + * Check two double precision floating point numbers to determine if X<≈Y + * with specified tolerance + * + * If not X <≈ Y with error < T, the test fails. + * + * @param X floating point number (long double) + * @param Y floating point number (long double) to compare against X + * @param T tolerance (long double) + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_le_tol(X, Y, T) _ck_assert_floating_op_tol(X, <, Y, T, 1, long double, "L") + +/** + * Check that a double precision floating point number is finite; i.e. is + * not +infinity, -infinity, or "Not a Number" (NaN) + * + * If X is +INFINITY or X is -INFINITY, or X is NaN, the test fails. + * + * @param X floating point number (long double) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_finite(X) _ck_assert_floating_finite(X, long double, "L") + +/** + * Check that a double precision floating point number is infinite, + * either +infinity or -infinity + * + * If X is not +INFINITY and X is not -INFINITY, the test fails. + * + * @param X floating point number (long double) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_infinite(X) _ck_assert_floating_infinite(X, long double, "L") + +/** + * Check that a double precision floating point number + * is "Not a Number" (NaN) + * + * If X is not NaN, the test fails. + * + * @param X floating point number (long double) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_nan(X) _ck_assert_floating_nan(X, long double, "L") + +/** + * Check that a double precision floating point number is + * not "Not a Number" (NaN) + * + * If X is NaN, the test fails. + * + * @param X floating point number (long double) to be checked + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ldouble_nonnan(X) _ck_assert_floating_nonnan(X, long double, "L") + +/* String comparison macros with improved output compared to ck_assert() */ +/* OP might be any operator that can be used in '0 OP strcmp(X,Y)' comparison. */ +/* String pointer could be compared againts NULL with == (NULLEQ = 1) and != (NULLNE = 1) operators. */ +/* The x and y parameter swap in strcmp() is needed to handle >, >=, <, <= operators. */ +/* If the x or y parameter is NULL its value will be printed without quotes. */ +#define _ck_assert_str(X, OP, Y, NULLEQ, NULLNE) do { \ + const char* _ck_x = (X); \ + const char* _ck_y = (Y); \ + const char* _ck_x_s; \ + const char* _ck_y_s; \ + const char* _ck_x_q; \ + const char* _ck_y_q; \ + if (_ck_x != NULL) { \ + _ck_x_q = "\""; \ + _ck_x_s = _ck_x; \ + } else { \ + _ck_x_q = ""; \ + _ck_x_s = "(null)"; \ + } \ + if (_ck_y != NULL) { \ + _ck_y_q = "\""; \ + _ck_y_s = _ck_y; \ + } else { \ + _ck_y_q = ""; \ + _ck_y_s = "(null)"; \ + } \ + ck_assert_msg( \ + (NULLEQ && (_ck_x == NULL) && (_ck_y == NULL)) || \ + (NULLNE && ((_ck_x == NULL) || (_ck_y == NULL)) && (_ck_x != _ck_y)) || \ + ((_ck_x != NULL) && (_ck_y != NULL) && (0 OP strcmp(_ck_y, _ck_x))), \ + "Assertion '%s' failed: %s == %s%s%s, %s == %s%s%s", \ + #X" "#OP" "#Y, \ + #X, _ck_x_q, _ck_x_s, _ck_x_q, \ + #Y, _ck_y_q, _ck_y_s, _ck_y_q); \ +} while (0) + +/** + * Check two strings to determine if 0==strcmp(X,Y) + * + * If X or Y is NULL the test fails. + * If not 0==strcmp(X,Y), the test fails. + * + * @param X string + * @param Y string to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.6 + */ +#define ck_assert_str_eq(X, Y) _ck_assert_str(X, ==, Y, 0, 0) + +/** + * Check two strings to determine if 0!=strcmp(X,Y) + * + * If X or Y is NULL the test fails. + * If not 0!=strcmp(X,Y), the test fails. + * + * @param X string + * @param Y string to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.6 + */ +#define ck_assert_str_ne(X, Y) _ck_assert_str(X, !=, Y, 0, 0) + +/** + * Check two strings to determine if 00) + * + * If X or Y is NULL the test fails. + * If not 0=0) + * + * If X or Y is NULL the test fails. + * If not 0<=strcmp(X,Y), the test fails. + * + * @param X string + * @param Y string to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.10 + */ +#define ck_assert_str_le(X, Y) _ck_assert_str(X, <=, Y, 0, 0) + +/** + * Check two strings to determine if 00) + * + * If X or Y is NULL the test fails. + * If not 0, Y, 0, 0) + +/** + * Check two strings to determine if 0>=strcmp(X,Y) (e.g. strcmp(X,Y)<=0) + * + * If X or Y is NULL the test fails. + * If not 0>=strcmp(X,Y), the test fails. + * + * @param X string + * @param Y string to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.10 + */ +#define ck_assert_str_ge(X, Y) _ck_assert_str(X, >=, Y, 0, 0) + +/** + * Check two strings to determine if 0==strcmp(X,Y) or if both are undefined + * + * If both X and Y are NULL the test passes. However, if only one is NULL + * the test fails. + * If not ((X==NULL)&&(Y==NULL)) || (0==strcmp(X,Y)), the test fails. + * + * @param X string + * @param Y string to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_pstr_eq(X, Y) _ck_assert_str(X, ==, Y, 1, 0) + +/** + * Check two strings to determine if 0!=strcmp(X,Y) or one of them is undefined + * + * If either X or Y is NULL the test passes, however if both are NULL + * the test fails. + * If not (X!=NULL)&&(Y!=NULL)&&(0!=strcmp(X,Y)), the test fails. + * + * @param X string + * @param Y string to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_pstr_ne(X, Y) _ck_assert_str(X, !=, Y, 0, 1) + +/* Memory location comparison macros with improved output compared to ck_assert() */ +/* OP might be any operator that can be used in '0 OP memcmp(X,Y,L)' comparison */ +/* The x and y parameter swap in memcmp() is needed to handle >, >=, <, <= operators */ +/* Output is limited to CK_MAX_ASSERT_MEM_PRINT_SIZE bytes */ +#ifndef CK_MAX_ASSERT_MEM_PRINT_SIZE +#define CK_MAX_ASSERT_MEM_PRINT_SIZE 64 +#endif + +/* Memory location comparison macros with improved output compared to ck_assert() */ +/* OP might be any operator that can be used in '0 OP memcmp(X,Y,L)' comparison */ +/* The x and y parameter swap in memcmp() is needed to handle >, >=, <, <= operators */ +/* Output is limited to CK_MAX_ASSERT_MEM_PRINT_SIZE bytes */ +#ifndef CK_MAX_ASSERT_MEM_PRINT_SIZE +#define CK_MAX_ASSERT_MEM_PRINT_SIZE 64 +#endif + +#define _ck_assert_mem(X, OP, Y, L) do { \ + const uint8_t* _ck_x = (const uint8_t*)(X); \ + const uint8_t* _ck_y = (const uint8_t*)(Y); \ + size_t _ck_l = (L); \ + char _ck_x_str[CK_MAX_ASSERT_MEM_PRINT_SIZE * 2 + 1]; \ + char _ck_y_str[CK_MAX_ASSERT_MEM_PRINT_SIZE * 2 + 1]; \ + static const char _ck_hexdigits[] = "0123456789abcdef"; \ + size_t _ck_i; \ + size_t _ck_maxl = (_ck_l > CK_MAX_ASSERT_MEM_PRINT_SIZE) ? CK_MAX_ASSERT_MEM_PRINT_SIZE : _ck_l; \ + for (_ck_i = 0; _ck_i < _ck_maxl; _ck_i++) { \ + _ck_x_str[_ck_i * 2 ] = _ck_hexdigits[(_ck_x[_ck_i] >> 4) & 0xF]; \ + _ck_y_str[_ck_i * 2 ] = _ck_hexdigits[(_ck_y[_ck_i] >> 4) & 0xF]; \ + _ck_x_str[_ck_i * 2 + 1] = _ck_hexdigits[_ck_x[_ck_i] & 0xF]; \ + _ck_y_str[_ck_i * 2 + 1] = _ck_hexdigits[_ck_y[_ck_i] & 0xF]; \ + } \ + _ck_x_str[_ck_i * 2] = 0; \ + _ck_y_str[_ck_i * 2] = 0; \ + if (_ck_maxl != _ck_l) { \ + _ck_x_str[_ck_i * 2 - 2] = '.'; \ + _ck_y_str[_ck_i * 2 - 2] = '.'; \ + _ck_x_str[_ck_i * 2 - 1] = '.'; \ + _ck_y_str[_ck_i * 2 - 1] = '.'; \ + } \ + ck_assert_msg(0 OP memcmp(_ck_y, _ck_x, _ck_l), \ + "Assertion '%s' failed: %s == \"%s\", %s == \"%s\"", #X" "#OP" "#Y, #X, _ck_x_str, #Y, _ck_y_str); \ +} while (0) +/** + * Check two memory locations to determine if 0==memcmp(X,Y,L) + * + * If not 0==memcmp(X,Y,L), the test fails. + * + * @param X memory location + * @param Y memory location to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_mem_eq(X, Y, L) _ck_assert_mem(X, ==, Y, L) +/** + * Check two memory locations to determine if 0!=memcmp(X,Y,L) + * + * If not 0!=memcmp(X,Y,L), the test fails. + * + * @param X memory location + * @param Y memory location to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_mem_ne(X, Y, L) _ck_assert_mem(X, !=, Y, L) +/** + * Check two memory locations to determine if 00) + * + * If not 0=0) + * + * If not 0<=memcmp(X,Y,L), the test fails. + * + * @param X memory location + * @param Y memory location to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_mem_le(X, Y, L) _ck_assert_mem(X, <=, Y, L) +/** + * Check two memory locations to determine if 00) + * + * If not 0, Y, L) +/** + * Check two memory locations to determine if 0>=memcmp(X,Y,L) (e.g. memcmp(X,Y,L)<=0) + * + * If not 0>=memcmp(X,Y,L), the test fails. + * + * @param X memory location + * @param Y memory location to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_mem_ge(X, Y, L) _ck_assert_mem(X, >=, Y, L) + +/* Pointer comparison macros with improved output compared to ck_assert(). */ +/* OP may only be == or != */ +#define _ck_assert_ptr(X, OP, Y) do { \ + const void* _ck_x = (X); \ + const void* _ck_y = (Y); \ + ck_assert_msg(_ck_x OP _ck_y, "Assertion '%s' failed: %s == %#lx, %s == %#lx", #X" "#OP" "#Y, #X, (unsigned long)(uintptr_t)_ck_x, #Y, (unsigned long)(uintptr_t)_ck_y); \ +} while (0) + +/* Pointer against NULL comparison macros with improved output + * compared to ck_assert(). */ +/* OP may only be == or != */ +#define _ck_assert_ptr_null(X, OP) do { \ + const void* _ck_x = (X); \ + ck_assert_msg(_ck_x OP NULL, \ + "Assertion '%s' failed: %s == %#lx", \ + #X" "#OP" NULL", \ + #X, (unsigned long)(uintptr_t)_ck_x); \ +} while (0) + +/** + * Check if two pointers are equal. + * + * If the two passed pointers are not equal, the test + * fails. + * + * @param X pointer + * @param Y pointer to compare against X + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.9.10 + */ +#define ck_assert_ptr_eq(X, Y) _ck_assert_ptr(X, ==, Y) + +/** + * Check if two pointers are not. + * + * If the two passed pointers are equal, the test fails. + * + * @param X pointer + * @param Y pointer to compare against X + * + * @since 0.9.10 + */ +#define ck_assert_ptr_ne(X, Y) _ck_assert_ptr(X, !=, Y) + +/** + * Check if a pointer is equal to NULL. + * + * If X != NULL, the test fails. + * + * @param X pointer to compare against NULL + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ptr_null(X) _ck_assert_ptr_null(X, ==) + +/** + * Check if a pointer is not equal to NULL. + * + * If X == NULL, the test fails. + * + * @param X pointer to compare against NULL + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ptr_nonnull(X) _ck_assert_ptr_null(X, !=) + +/** + * Mark the last point reached in a unit test. + * + * If the test throws a signal or exits, the location noted with the + * failure is the last location of a ck_assert*() or ck_abort() call. + * Use mark_point() to record intermediate locations (useful for tracking down + * crashes or exits). + * + * @since 0.6.0 +*/ +#define mark_point() _mark_point(__FILE__,__LINE__) + +/* Non macro version of #mark_point */ +CK_DLL_EXP void CK_EXPORT _mark_point(const char *file, int line); + +/** + * Enum describing the possible results of a test + */ +enum test_result +{ + CK_TEST_RESULT_INVALID, /**< Default value; should not encounter this */ + CK_PASS, /**< Test passed */ + CK_FAILURE, /**< Test completed but failed */ + CK_ERROR /**< Test failed to complete + (unexpected signal or non-zero early exit) */ +}; + +/** + * Enum specifying the verbosity of output a SRunner should produce + */ +enum print_output +{ + CK_SILENT, /**< No output */ + CK_MINIMAL, /**< Only summary output */ + CK_NORMAL, /**< All failed tests */ + CK_VERBOSE, /**< All tests */ + CK_ENV, /**< Look at environment var CK_VERBOSITY + for what verbosity to use, which can be + either "silent", "minimal", "normal", + or "verbose". If the environment variable + is not set, then CK_NORMAL will be used.*/ +#if 0 + CK_SUBUNIT, /**< Run as a subunit child process */ +#endif + CK_LAST /**< Not a valid option */ +}; + +/** + * Holds state for a running of a test suite + */ +typedef struct SRunner SRunner; + +/** + * Opaque type for a test failure + */ +typedef struct TestResult TestResult; + +/** + * Enum representing the types of contexts for a test + */ +enum ck_result_ctx +{ + CK_CTX_INVALID, /**< Default value; should not encounter this */ + CK_CTX_SETUP, /**< Setup before a test */ + CK_CTX_TEST, /**< Body of test itself */ + CK_CTX_TEARDOWN /**< Teardown after a test */ +}; + +/** + * Retrieve type of result that the given test result represents. + * + * This is a member of test_result, and can represent a + * pass, failure, or error. + * + * @param tr test result to retrieve result from + * + * @return result of given test + * + * @since 0.6.0 + */ +CK_DLL_EXP int CK_EXPORT tr_rtype(TestResult * tr); + +/** + * Retrieve context in which the result occurred for the given test result. + * + * The types of contents include the test setup, teardown, or the + * body of the test itself. + * + * @param tr test result to retrieve context from + * + * @return context to which the given test result applies + * + * @since 0.8.0 + */ +CK_DLL_EXP enum ck_result_ctx CK_EXPORT tr_ctx(TestResult * tr); + +/** + * Retrieve failure message from test result, if applicable. + * + * @return pointer to a message, if one exists. NULL otherwise. + * + * @since 0.6.0 + */ +CK_DLL_EXP const char *CK_EXPORT tr_msg(TestResult * tr); + +/** + * Retrieve line number at which a failure occurred, if applicable. + * + * @return If the test resulted in a failure, returns the line number + * that the failure occurred on; otherwise returns -1. + * + * @since 0.6.0 + */ +CK_DLL_EXP int CK_EXPORT tr_lno(TestResult * tr); + +/** + * Retrieve file name at which a failure occurred, if applicable. + * + * @return If the test resulted in a failure, returns a string + * containing the name of the file where the failure + * occurred; otherwise returns NULL. + * + * @since 0.6.0 + */ +CK_DLL_EXP const char *CK_EXPORT tr_lfile(TestResult * tr); + +/** + * Retrieve test case name in which a failure occurred, if applicable. + * + * @return If the test resulted in a failure, returns a string + * containing the name of the test suite where the failure + * occurred; otherwise returns NULL. + * + * @since 0.6.0 + */ +CK_DLL_EXP const char *CK_EXPORT tr_tcname(TestResult * tr); + +/** + * Creates a suite runner for the given suite. + * + * Once created, additional suites can be added to the + * suite runner using srunner_add_suite(), and the suite runner can be + * run with srunner_run_all(). Once finished, the suite runner + * must be freed with srunner_free(). + * + * @param s suite to generate a suite runner for + * + * @return suite runner for the given suite + * + * @since 0.6.0 + */ +CK_DLL_EXP SRunner *CK_EXPORT srunner_create(Suite * s); + +/** + * Add an additional suite to a suite runner. + * + * The first suite in a suite runner is always added in srunner_create(). + * This call adds additional suites to a suite runner. + * + * @param sr suite runner to add the given suite + * @param s suite to add to the given suite runner + * + * @since 0.7.0 + */ +CK_DLL_EXP void CK_EXPORT srunner_add_suite(SRunner * sr, Suite * s); + +/** + * Frees a suite runner, including all contained suite and test cases. + * + * This call is responsible for freeing all resources related to a + * suite runner and all contained suites and test cases. Suite and + * test cases need not be freed individually, as this call handles that. + * + * @param sr suite runner to free + * + * @since 0.6.0 + */ +CK_DLL_EXP void CK_EXPORT srunner_free(SRunner * sr); + +/** + * Runs a suite runner and all contained suite, printing results to + * stdout as specified by the print_mode. + * + * In addition to running all suites, if the suite runner has been + * configured to output to a log, that is also performed. + * + * Note that if the CK_RUN_CASE, CK_RUN_SUITE, CK_INCLUDE_TAGS and/or + * CK_EXCLUDE_TAGS environment variables are defined, then only the + * named suites or test cases will run. + * + * @param sr suite runner to run all suites from + * @param print_mode the verbosity in which to report results to stdout + * + * @since 0.6.0 + */ +CK_DLL_EXP void CK_EXPORT srunner_run_all(SRunner * sr, + enum print_output print_mode); + +/** + * Run a specific suite or test case from a suite runner, printing results + * to stdout as specified by the print_mode. + * + * In addition to running any applicable suites or test cases, if the + * suite runner has been configured to output to a log, that is also + * performed. + * + * Note that if the sname and tcname parameters are passed as null + * then the function will fallback to using the environment variables + * CK_RUN_SUITE and CK_RUN_CASE respectively in order to select the + * suite/cases. + * + * Similarly if the CK_INCLUDE_TAGS and/or CK_EXCLUDE_TAGS environment + * variables are defined then these will further filter the test cases + * (see srunner_run_tagged, below). + * + * @param sr suite runner where the given suite or test case must be + * @param sname suite name to run. A NULL means use the value of the + * environment variable CK_RUN_SUITE if set, otherwise run "any/every + * suite". + * @param tcname test case name to run. A NULL means use the value of + * the environment variable CK_RUN_CASE if set, otherwise run + * "any/every case". + * @param print_mode the verbosity in which to report results to stdout + * + * @since 0.9.9 + */ +CK_DLL_EXP void CK_EXPORT srunner_run(SRunner * sr, const char *sname, + const char *tcname, + enum print_output print_mode); + + +/** + * Run a specific suite or test case or testcases with specific tags + * from a suite runner, printing results to stdout as specified by the + * print_mode. + * + * In addition to running any applicable suites or test cases, if the + * suite runner has been configured to output to a log, that is also + * performed. + * + * Note that if sname, tcname, include_tags, exclude_tags parameters + * are passed as NULL then if the environment variables CK_RUN_SUITE, + * CK_RUN_CASE, CK_INCLUDE_TAGS, CK_EXCLUDE_TAGS are defined then these + * values will be used instead. + * + * @param sr suite runner where the given suite or test case must be + * @param sname suite name to run. A NULL means use the value of the + * environment variable CK_RUN_SUITE if set, otherwise run "any/every + * suite". + * @param tcname test case name to run. A NULL means use the value of + * the environment variable CK_RUN_CASE if set, otherwise run + * "any/every case". + * @param include_tags space separate list of tags. Only run test + * cases that share one of these tags. A NULL means use the value of + * the environment variable CK_INCLUDE_TAGS if set, otherwise run + * "any/every test case". + * @param exclude_tags space separate list of tags. Only run test + * cases that do not share one of these tags even if they are selected + * by an included tag. A NULL means use the value of the environment + * variable CK_EXCLUDE_TAGS if set, otherwise run "any/every test + * case". + * @param print_mode the verbosity in which to report results to stdout + * + * @since 0.11.0 + */ +CK_DLL_EXP void CK_EXPORT srunner_run_tagged(SRunner * sr, const char *sname, + const char *tcname, + const char *include_tags, + const char *exclude_tags, + enum print_output print_mode); + +/** + * Retrieve the number of failed tests executed by a suite runner. + * + * This value represents both test failures and errors. + * + * @param sr suite runner to query for all failed tests + * + * @return number of test failures and errors found by the suite runner + * + * @since 0.6.1 + */ +CK_DLL_EXP int CK_EXPORT srunner_ntests_failed(SRunner * sr); + +/** + * Retrieve the total number of tests run by a suite runner. + * + * @param sr suite runner to query for all tests run + * + * @return number of all tests run by the suite runner + * + * @since 0.6.1 + */ +CK_DLL_EXP int CK_EXPORT srunner_ntests_run(SRunner * sr); + +/** + * Return an array of results for all failures found by a suite runner. + * + * Number of results is equal to srunner_nfailed_tests(). + * + * Information about individual results can be queried using: + * tr_rtype(), tr_ctx(), tr_msg(), tr_lno(), tr_lfile(), and tr_tcname(). + * + * Memory is malloc'ed and must be freed; however free the entire structure + * instead of individual test cases. + * + * @param sr suite runner to retrieve results from + * + * @return array of TestResult objects + * + * @since 0.6.0 + */ +CK_DLL_EXP TestResult **CK_EXPORT srunner_failures(SRunner * sr); + +/** + * Return an array of results for all tests run by a suite runner. + * + * Number of results is equal to srunner_ntests_run(), and excludes + * failures due to setup function failure. + * + * Information about individual results can be queried using: + * tr_rtype(), tr_ctx(), tr_msg(), tr_lno(), tr_lfile(), and tr_tcname(). + * + * Memory is malloc'ed and must be freed; however free the entire structure + * instead of individual test cases. + * + * @param sr suite runner to retrieve results from + * + * @return array of TestResult objects + * + * @since 0.6.1 +*/ +CK_DLL_EXP TestResult **CK_EXPORT srunner_results(SRunner * sr); + +/** + * Print the results contained in an SRunner to stdout. + * + * @param sr suite runner to print results for to stdout + * @param print_mode the print_output (verbosity) to use to report + * the result + * + * @since 0.7.0 + */ +CK_DLL_EXP void CK_EXPORT srunner_print(SRunner * sr, + enum print_output print_mode); + +/** + * Set the suite runner to output the result in log format to the + * given file. + * + * Note: log file setting is an initialize only operation -- it should + * be done immediately after SRunner creation, and the log file can't be + * changed after being set. + * + * This setting does not conflict with the other log output types; + * all logging types can occur concurrently if configured. + * + * @param sr suite runner to log results of in log format + * @param fname file name to output log results to + * + * @since 0.7.1 +*/ +CK_DLL_EXP void CK_EXPORT srunner_set_log(SRunner * sr, const char *fname); + +/** + * Checks if the suite runner is assigned a file for log output. + * + * @param sr suite runner to check + * + * @return 1 iff the suite runner currently is configured to output + * in log format; 0 otherwise + * + * @since 0.7.1 + */ +CK_DLL_EXP int CK_EXPORT srunner_has_log(SRunner * sr); + +/** + * Retrieves the name of the currently assigned file + * for log output, if any exists. + * + * @return the name of the log file, or NULL if none is configured + * + * @since 0.7.1 + */ +CK_DLL_EXP const char *CK_EXPORT srunner_log_fname(SRunner * sr); + +/** + * Set the suite runner to output the result in XML format to the + * given file. + * + * Note: XML file setting is an initialize only operation -- it should + * be done immediately after SRunner creation, and the XML file can't be + * changed after being set. + * + * This setting does not conflict with the other log output types; + * all logging types can occur concurrently if configured. + * + * @param sr suite runner to log results of in XML format + * @param fname file name to output XML results to + * + * @since 0.9.1 +*/ +CK_DLL_EXP void CK_EXPORT srunner_set_xml(SRunner * sr, const char *fname); + +/** + * Checks if the suite runner is assigned a file for XML output. + * + * @param sr suite runner to check + * + * @return 1 iff the suite runner currently is configured to output + * in XML format; 0 otherwise + * + * @since 0.9.1 + */ +CK_DLL_EXP int CK_EXPORT srunner_has_xml(SRunner * sr); + +/** + * Retrieves the name of the currently assigned file + * for XML output, if any exists. + * + * @return the name of the XML file, or NULL if none is configured + * + * @since 0.9.1 + */ +CK_DLL_EXP const char *CK_EXPORT srunner_xml_fname(SRunner * sr); + +/** + * Set the suite runner to output the result in TAP format to the + * given file. + * + * Note: TAP file setting is an initialize only operation -- it should + * be done immediately after SRunner creation, and the TAP file can't be + * changed after being set. + * + * This setting does not conflict with the other log output types; + * all logging types can occur concurrently if configured. + * + * @param sr suite runner to log results of in TAP format + * @param fname file name to output TAP results to + * + * @since 0.9.12 +*/ +CK_DLL_EXP void CK_EXPORT srunner_set_tap(SRunner * sr, const char *fname); + +/** + * Checks if the suite runner is assigned a file for TAP output. + * + * @param sr suite runner to check + * + * @return 1 iff the suite runner currently is configured to output + * in TAP format; 0 otherwise + * + * @since 0.9.12 + */ +CK_DLL_EXP int CK_EXPORT srunner_has_tap(SRunner * sr); + +/** + * Retrieves the name of the currently assigned file + * for TAP output, if any exists. + * + * @return the name of the TAP file, or NULL if none is configured + * + * @since 0.9.12 + */ +CK_DLL_EXP const char *CK_EXPORT srunner_tap_fname(SRunner * sr); + +/** + * Enum describing the current fork usage. + */ +enum fork_status +{ + CK_FORK_GETENV, /**< look in the environment for CK_FORK */ + CK_FORK, /**< call fork to run tests */ + CK_NOFORK /**< don't call fork */ +}; + +/** + * Retrieve the current fork status for the given suite runner + * + * @param sr suite runner to check fork status of + * + * @since 0.8.0 + */ +CK_DLL_EXP enum fork_status CK_EXPORT srunner_fork_status(SRunner * sr); + +/** + * Set the fork status for a given suite runner. + * + * The default fork status is CK_FORK_GETENV, which will look + * for the CK_FORK environment variable, which can be set to + * "yes" or "no". If the environment variable is not present, + * CK_FORK will be used if fork() is available on the system, + * otherwise CK_NOFORK is used. + * + * If set to CK_FORK or CK_NOFORK, the environment variable + * if defined is ignored. + * + * If Check is compiled without support for fork(), attempting + * to set the status to CK_FORK is ignored. + * + * @param sr suite runner to assign the fork status to + * @param fstat fork status to assign + * + * @since 0.8.0 + */ +CK_DLL_EXP void CK_EXPORT srunner_set_fork_status(SRunner * sr, + enum fork_status fstat); + +/** + * Invoke fork() during a test and assign the child to the same + * process group that the rest of the test case uses. + * + * One can invoke fork() directly during a test; however doing so + * may not guarantee that any children processes are destroyed once + * the test finishes. Once a test has completed, all processes in + * the process group will be killed; using this wrapper will prevent + * orphan processes. + * + * If Check is compiled without fork() support this call simply + * return -1 and does nothing. + * + * @return On success, the PID of the child process is returned in + * the parent, and 0 is returned in the child. On failure, + * a value of -1 is returned to the parent process and no + * child process is created. + * + * @since 0.9.3 + */ +CK_DLL_EXP pid_t CK_EXPORT check_fork(void); + +/** + * Wait for the pid and exit. + * + * This is to be used in conjunction with check_fork(). When called, + * will wait for the given process to terminate. If the process + * exited without error, exit(EXIT_SUCCESS) is invoked; otherwise + * exit(EXIT_FAILURE) is invoked. + * + * If Check is compiled without support for fork(), this invokes + * exit(EXIT_FAILURE). + * + * @param pid process to wait for, created by check_fork() + * + * @since 0.9.3 + */ +CK_DLL_EXP void CK_EXPORT check_waitpid_and_exit(pid_t pid) CK_ATTRIBUTE_NORETURN; + +/** + * Set the maximal assertion message size. + * + * This protects the code against unintentional extremely large assertion messages + * (values of up to 4GB were seen in the wild). + * The usual size for a message is less than 80 bytes. + * + * If the environment variable CK_MAX_MSG_SIZE is defined to a positive value, it is used. + * Otherwise, if a positive maximal message size is set via this function, it is used. + * Otherwise, the maximal message size is one assigned at compile time (4K bytes). + * + * @param max_msg_size the maximal assertion message size. + * + * @since 0.12.0 + */ +CK_DLL_EXP void CK_EXPORT check_set_max_msg_size(size_t max_msg_size); + +#ifdef __cplusplus +CK_CPPEND +#endif + +#endif /* CHECK_H */ -- Gitee From 7fd22da4a342a90351260a8ce028b6ae50ccba35 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Fri, 11 Feb 2022 20:57:32 +0800 Subject: [PATCH 04/34] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E9=93=BE=E8=A1=A8?= =?UTF-8?q?=E7=9A=84=E6=9E=84=E5=BB=BA=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 yonglin_zhang/link_list/CMakeLists.txt diff --git a/yonglin_zhang/link_list/CMakeLists.txt b/yonglin_zhang/link_list/CMakeLists.txt new file mode 100644 index 0000000..a9289c2 --- /dev/null +++ b/yonglin_zhang/link_list/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(src) +add_subdirectory(test) \ No newline at end of file -- Gitee From 9abbb796243ff73c4fc782172da210c67882b240 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Fri, 11 Feb 2022 21:57:24 +0800 Subject: [PATCH 05/34] =?UTF-8?q?=E5=A3=B0=E6=98=8E=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/include/link_list.h | 33 +++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 yonglin_zhang/link_list/include/link_list.h diff --git a/yonglin_zhang/link_list/include/link_list.h b/yonglin_zhang/link_list/include/link_list.h new file mode 100644 index 0000000..5b3b013 --- /dev/null +++ b/yonglin_zhang/link_list/include/link_list.h @@ -0,0 +1,33 @@ +/** + * \file 链表头文件 +*/ + +#ifndef LINK_LIST_H +#define LINK_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "alg_errno.h" + +typedef int data_type; +typedef struct _link_list link_list; + +/** + * \brief 句柄初始化 + * + * \warning ctx必须为二级指针,为了防止内存泄漏,请保证ctx为NULL + * + * \param ctx[out] 初始化句柄 + * + * \return \c ALG_OK 初始化成功 +*/ +int list_init(link_list **ctx); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file -- Gitee From 7badee64538c9334f781e3d1bee929211a9c5a12 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Fri, 11 Feb 2022 21:57:44 +0800 Subject: [PATCH 06/34] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/src/link_list.c | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 yonglin_zhang/link_list/src/link_list.c diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c new file mode 100644 index 0000000..d98af21 --- /dev/null +++ b/yonglin_zhang/link_list/src/link_list.c @@ -0,0 +1,30 @@ +#include +#include +#include "link_list.h" +#include "alg_errno.h" + +typedef struct _link_list{ + data_type data; + void *next; +}; + +typedef struct _link_list node; + +/* 初始化句柄 */ +int list_init(link_list **ctx) +{ + if(*ctx != NULL) { + return ALG_BAD_INPUT; + } + + *ctx = (node *)malloc(sizeof(node)); + + (*ctx)->data = 0; + (*ctx)->next = NULL; + + if(*ctx == NULL) { + return ALG_MALLOC_FAIL; + } + + return ALG_OK; +} \ No newline at end of file -- Gitee From f206d52705845108bec9c02a90bed85f6fe4d659 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Fri, 11 Feb 2022 22:06:46 +0800 Subject: [PATCH 07/34] =?UTF-8?q?=E4=BF=AE=E6=94=B9cmake=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/src/CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 yonglin_zhang/link_list/src/CMakeLists.txt diff --git a/yonglin_zhang/link_list/src/CMakeLists.txt b/yonglin_zhang/link_list/src/CMakeLists.txt new file mode 100644 index 0000000..00fdc3d --- /dev/null +++ b/yonglin_zhang/link_list/src/CMakeLists.txt @@ -0,0 +1,12 @@ +set(LIB_SRC + link_list.c +) + +set(INCLUDE_DIR + ${CMAKE_CURRENT_SOURCE_DIR}/../include + ${CMAKE_CURRENT_SOURCE_DIR}/../../include +) + +include_directories(${INCLUDE_DIR}) + +add_library(${LINK_SDK_NAME} SHARED ${LIB_SRC}) \ No newline at end of file -- Gitee From 41903711c7a4820a60acf5a91690f3b3b6182ad6 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Fri, 11 Feb 2022 22:07:15 +0800 Subject: [PATCH 08/34] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/src/link_list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c index d98af21..537971b 100644 --- a/yonglin_zhang/link_list/src/link_list.c +++ b/yonglin_zhang/link_list/src/link_list.c @@ -3,7 +3,7 @@ #include "link_list.h" #include "alg_errno.h" -typedef struct _link_list{ +struct _link_list{ data_type data; void *next; }; -- Gitee From 06dbd73f5f3733c54d13957293cb4ef43ade307d Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Fri, 11 Feb 2022 22:07:34 +0800 Subject: [PATCH 09/34] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/include/alg_errno.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yonglin_zhang/include/alg_errno.h b/yonglin_zhang/include/alg_errno.h index df7372e..41ad7b1 100644 --- a/yonglin_zhang/include/alg_errno.h +++ b/yonglin_zhang/include/alg_errno.h @@ -9,9 +9,9 @@ extern "C" { #endif -#define ALG_OK 0x0000 执行成功 -#define ALG_BAD_INPUT 0x0001 输入数据不合法 -#define ALG_MALLOC_FAIL 0x0002 内存空间不足 +#define ALG_OK 0x0000 // 执行成功 +#define ALG_BAD_INPUT 0x0001 // 输入数据不合法 +#define ALG_MALLOC_FAIL 0x0002 // 内存空间不足 #ifdef __cplusplus } -- Gitee From f49413fac0abe93bede55d0df9c8487f29a20972 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Fri, 11 Feb 2022 22:07:57 +0800 Subject: [PATCH 10/34] =?UTF-8?q?=E4=BF=AE=E6=94=B9cmake?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/yonglin_zhang/link_list/CMakeLists.txt b/yonglin_zhang/link_list/CMakeLists.txt index a9289c2..9d0cad6 100644 --- a/yonglin_zhang/link_list/CMakeLists.txt +++ b/yonglin_zhang/link_list/CMakeLists.txt @@ -1,2 +1,4 @@ +set(LINK_SDK_NAME "link_list") + add_subdirectory(src) -add_subdirectory(test) \ No newline at end of file +# add_subdirectory(test) \ No newline at end of file -- Gitee From 13e93be8a9d44d544f27815708ee3cfad49c478d Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 20:03:37 +0800 Subject: [PATCH 11/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=B4=E6=8F=92?= =?UTF-8?q?=E6=B3=95=E5=92=8C=E5=B0=BE=E6=8F=92=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/include/link_list.h | 20 ++++++++++ yonglin_zhang/link_list/src/link_list.c | 42 +++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/yonglin_zhang/link_list/include/link_list.h b/yonglin_zhang/link_list/include/link_list.h index 5b3b013..ecd89ae 100644 --- a/yonglin_zhang/link_list/include/link_list.h +++ b/yonglin_zhang/link_list/include/link_list.h @@ -26,6 +26,26 @@ typedef struct _link_list link_list; */ int list_init(link_list **ctx); +/** + * \brief 头部添加一个节点 + * + * \param ctx[in] 指针句柄 + * \param data[in] 待插入数据 + * + * \return \c ALG_OK 添加成功 +*/ +int list_add_head(link_list *ctx, data_type data); + +/** + * \brief 尾部添加一个节点 + * + * \param ctx[in] 指针句柄 + * \param data[in] 待插入数据 + * + * \return \c ALG_OK 添加成功 +*/ +int list_add_rear(link_list *ctx, data_type data); + #ifdef __cplusplus } #endif diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c index 537971b..f4b6dcd 100644 --- a/yonglin_zhang/link_list/src/link_list.c +++ b/yonglin_zhang/link_list/src/link_list.c @@ -26,5 +26,47 @@ int list_init(link_list **ctx) return ALG_MALLOC_FAIL; } + return ALG_OK; +} + +/* 头部插入一个节点 */ +int list_add_head(link_list *ctx, data_type data) +{ + node *t = NULL; + + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + + t = (node *)malloc(sizeof(node)); + t->data = data; + t->next = ctx->next; + + ctx->next = t; +} + +/* 尾部插入一个节点 */ +int list_add_rear(link_list *ctx, data_type data) +{ + node *t = NULL, *p = NULL; + + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + + t = (node *)malloc(sizeof(node)); + if(t == NULL) { + return ALG_MALLOC_FAIL; + } + + t->next = NULL; + t->data = data; + + p = ctx; + while(p->next != NULL) { + p = p->next; + } + p->next = t; + return ALG_OK; } \ No newline at end of file -- Gitee From e7da9abc471876dfded0e0b2165162f62a8a8545 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 20:10:39 +0800 Subject: [PATCH 12/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E9=93=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/include/link_list.h | 9 ++++++++ yonglin_zhang/link_list/src/link_list.c | 25 +++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/yonglin_zhang/link_list/include/link_list.h b/yonglin_zhang/link_list/include/link_list.h index ecd89ae..b52c45c 100644 --- a/yonglin_zhang/link_list/include/link_list.h +++ b/yonglin_zhang/link_list/include/link_list.h @@ -46,6 +46,15 @@ int list_add_head(link_list *ctx, data_type data); */ int list_add_rear(link_list *ctx, data_type data); +/** + * \brief 打印链表中的所有内容 + * + * \param ctx[in] 指针句柄 + * + * \return \c ALG_OK 打印完毕 +*/ +int list_show(link_list *ctx); + #ifdef __cplusplus } #endif diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c index f4b6dcd..8510237 100644 --- a/yonglin_zhang/link_list/src/link_list.c +++ b/yonglin_zhang/link_list/src/link_list.c @@ -68,5 +68,30 @@ int list_add_rear(link_list *ctx, data_type data) } p->next = t; + return ALG_OK; +} + +/* 打印链表 */ +int list_show(link_list *ctx) +{ + node *t = NULL; + + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + if(ctx->next == NULL) { + return ALG_BAD_INPUT; + } + + t = ctx->next; + + printf("%d", t->data); + t = t->next; + + while(t != NULL) { + printf("->%d", t->data); + t = t->next; + } + return ALG_OK; } \ No newline at end of file -- Gitee From 2281a9ca959603e94cf6aaed576efd70f0b65861 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 20:27:00 +0800 Subject: [PATCH 13/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B8=85=E7=A9=BA?= =?UTF-8?q?=E9=93=BE=E8=A1=A8=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/include/link_list.h | 9 ++++++++ yonglin_zhang/link_list/src/link_list.c | 23 +++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/yonglin_zhang/link_list/include/link_list.h b/yonglin_zhang/link_list/include/link_list.h index b52c45c..a87cfa1 100644 --- a/yonglin_zhang/link_list/include/link_list.h +++ b/yonglin_zhang/link_list/include/link_list.h @@ -46,6 +46,15 @@ int list_add_head(link_list *ctx, data_type data); */ int list_add_rear(link_list *ctx, data_type data); +/** + * \brief 清空链表中的元素 + * + * \param ctx[in] 指针句柄 + * + * \return \c ALG_OK 执行成功 +*/ +int list_clean(link_list *ctx); + /** * \brief 打印链表中的所有内容 * diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c index 8510237..a41faa8 100644 --- a/yonglin_zhang/link_list/src/link_list.c +++ b/yonglin_zhang/link_list/src/link_list.c @@ -71,6 +71,29 @@ int list_add_rear(link_list *ctx, data_type data) return ALG_OK; } +/* 清空链表 */ +int list_clean(link_list *ctx) +{ + node *t = NULL; + + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + + if(ctx->next == NULL) { + return ALG_OK; + } + + t = ctx->next; + while(t != NULL) { + node *temp = t; + t = t->next; + free(temp); + } + + return ALG_OK; +} + /* 打印链表 */ int list_show(link_list *ctx) { -- Gitee From 87e8a0aab44069d564c7dca35d96ebc067a4f635 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 20:39:48 +0800 Subject: [PATCH 14/34] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=90=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/include/alg_errno.h | 1 + 1 file changed, 1 insertion(+) diff --git a/yonglin_zhang/include/alg_errno.h b/yonglin_zhang/include/alg_errno.h index 41ad7b1..55d4123 100644 --- a/yonglin_zhang/include/alg_errno.h +++ b/yonglin_zhang/include/alg_errno.h @@ -12,6 +12,7 @@ extern "C" { #define ALG_OK 0x0000 // 执行成功 #define ALG_BAD_INPUT 0x0001 // 输入数据不合法 #define ALG_MALLOC_FAIL 0x0002 // 内存空间不足 +#define ALG_NODE_NOT_EXIST 0x0003 // 目标节点不存在 #ifdef __cplusplus } -- Gitee From 7e51919b2d1ee2a4a8222580adda83f7a5d9e285 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 20:41:57 +0800 Subject: [PATCH 15/34] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E7=9A=84=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/include/link_list.h | 10 +++++++ yonglin_zhang/link_list/src/link_list.c | 29 ++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/yonglin_zhang/link_list/include/link_list.h b/yonglin_zhang/link_list/include/link_list.h index a87cfa1..a189be9 100644 --- a/yonglin_zhang/link_list/include/link_list.h +++ b/yonglin_zhang/link_list/include/link_list.h @@ -46,6 +46,16 @@ int list_add_head(link_list *ctx, data_type data); */ int list_add_rear(link_list *ctx, data_type data); +/** + * \brief 删除链表中第一个为target的元素 + * + * \param ctx[in] 指针句柄 + * \param target[in] 目标元素 + * + * \return \c ALG_OK 删除成功 +*/ +int lint_delete_first_target(link_list *ctx, data_type target); + /** * \brief 清空链表中的元素 * diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c index a41faa8..14010ad 100644 --- a/yonglin_zhang/link_list/src/link_list.c +++ b/yonglin_zhang/link_list/src/link_list.c @@ -5,7 +5,7 @@ struct _link_list{ data_type data; - void *next; + struct _link_list *next; }; typedef struct _link_list node; @@ -71,6 +71,33 @@ int list_add_rear(link_list *ctx, data_type data) return ALG_OK; } +/* 删除第一个为target元素的节点 */ +int lint_delete_first_target(link_list *ctx, data_type target) +{ + node *t = NULL; + + if(ctx == NULL) { + return ALG_BAD_INPUT; + } + + if(ctx->next == NULL) { + return ALG_BAD_INPUT; + } + + t = ctx; + while(t->next != NULL) { + if(t->next->data == target) { + node *temp = t->next; + t->next = temp->next; + free(t); + return ALG_OK; + } + t = t->next; + } + + return ALG_NODE_NOT_EXIST; +} + /* 清空链表 */ int list_clean(link_list *ctx) { -- Gitee From 4e95c8c34a02a3fc5fcee0f6ad388306d58f857a Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 21:02:38 +0800 Subject: [PATCH 16/34] =?UTF-8?q?=E5=A3=B0=E6=98=8E=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/test/check_interface.h | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 yonglin_zhang/link_list/test/check_interface.h diff --git a/yonglin_zhang/link_list/test/check_interface.h b/yonglin_zhang/link_list/test/check_interface.h new file mode 100644 index 0000000..82b9fe7 --- /dev/null +++ b/yonglin_zhang/link_list/test/check_interface.h @@ -0,0 +1,8 @@ +#ifndef CHECK_INTERFACE_H +#define CHECK_INTERFACE_H + +#include "check.h" + +Suite *check_init(void); + +#endif; \ No newline at end of file -- Gitee From c9c52b5561daa49fa702e39a033d212b6fd60cf5 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 21:09:32 +0800 Subject: [PATCH 17/34] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/test/check_interface.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 yonglin_zhang/link_list/test/check_interface.c diff --git a/yonglin_zhang/link_list/test/check_interface.c b/yonglin_zhang/link_list/test/check_interface.c new file mode 100644 index 0000000..ea6a007 --- /dev/null +++ b/yonglin_zhang/link_list/test/check_interface.c @@ -0,0 +1,15 @@ +#include +#include "check_interface.h" + +int main() +{ + SRunner *sr; + + sr = srunner_create(check_init()); + + srunner_set_fork_status(sr, CK_NOFORK); + + srunner_run_all(sr, CK_VERBOSE); + + srunner_free(sr); +} \ No newline at end of file -- Gitee From b7092b1ba2f7e52ac44b81871495d86238663398 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 21:18:28 +0800 Subject: [PATCH 18/34] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=94=A8=E4=BE=8B?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/test/check_init.c | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 yonglin_zhang/link_list/test/check_init.c diff --git a/yonglin_zhang/link_list/test/check_init.c b/yonglin_zhang/link_list/test/check_init.c new file mode 100644 index 0000000..ad7b330 --- /dev/null +++ b/yonglin_zhang/link_list/test/check_init.c @@ -0,0 +1,25 @@ +#include + +#include "check_interface.h" +#include "link_list.h" +#include "alg_errno.h" + +START_TEST(test_init) +{ + link_list *ctx = NULL; + ck_assert_int_eq(list_init(&ctx), ALG_OK); +} +END_TEST + +Suite *check_init(void) +{ + Suite *s; + TCase *tc_core; + + s = suite_create("list_init test"); + + tc_core = tcase_create("core"); + tcase_add_test(tc_core, test_init); + + suite_add_tcase(s, tc_core); +} \ No newline at end of file -- Gitee From 0525f4a9297df0a543d7bffa56fc3a6c7284a8e3 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 21:33:52 +0800 Subject: [PATCH 19/34] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E6=B5=8B=E8=AF=95cmake?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/test/CMakeLists.txt | 35 +++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 yonglin_zhang/link_list/test/CMakeLists.txt diff --git a/yonglin_zhang/link_list/test/CMakeLists.txt b/yonglin_zhang/link_list/test/CMakeLists.txt new file mode 100644 index 0000000..e4f4ee1 --- /dev/null +++ b/yonglin_zhang/link_list/test/CMakeLists.txt @@ -0,0 +1,35 @@ +set(INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/. + ${CMAKE_CURRENT_SOURCE_DIR}/../include + ${CMAKE_CURRENT_SOURCE_DIR}/../../include +) + +set(DEP_LIBS + check + link_list + check_interface +) + +set(DEP_LIBS_DIR + ${CMAKE_SOURCE_DIR}/build/unit-testing/src/ + ${CMAKE_SOURCE_DIR}/build/link_list/src/ + ${CMAKE_SOURCE_DIR}/build/link_list/test/ +) + +set(SRC + check_init.c + check_interface.c +) + +set(TEST_LIB_NAME + check_interface +) + +link_directories(${DEP_LIBS_DIR}) +include_directories(${INCLUDE_DIRS}) + +add_library(${TEST_LIB_NAME} SHARED ${SRC}) +add_library(${TEST_LIB_NAME} STATIC ${SRC}) + +add_executable(check_interface check_interface.c) +target_link_libraries(check_interface ${DEP_LIBS}) \ No newline at end of file -- Gitee From faa5600a84d325ca95508d08cbf6e69f91fc4b54 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 21:34:26 +0800 Subject: [PATCH 20/34] =?UTF-8?q?=E6=89=93=E5=BC=80=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yonglin_zhang/link_list/CMakeLists.txt b/yonglin_zhang/link_list/CMakeLists.txt index 9d0cad6..0809288 100644 --- a/yonglin_zhang/link_list/CMakeLists.txt +++ b/yonglin_zhang/link_list/CMakeLists.txt @@ -1,4 +1,4 @@ set(LINK_SDK_NAME "link_list") add_subdirectory(src) -# add_subdirectory(test) \ No newline at end of file +add_subdirectory(test) \ No newline at end of file -- Gitee From 8ed0b253e7dcdc65e59a5cf73b5b2dc97ce4f43f Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 21:34:49 +0800 Subject: [PATCH 21/34] =?UTF-8?q?=E7=BC=96=E8=AF=91=E9=9D=99=E6=80=81?= =?UTF-8?q?=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/src/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/yonglin_zhang/link_list/src/CMakeLists.txt b/yonglin_zhang/link_list/src/CMakeLists.txt index 00fdc3d..1fc434a 100644 --- a/yonglin_zhang/link_list/src/CMakeLists.txt +++ b/yonglin_zhang/link_list/src/CMakeLists.txt @@ -9,4 +9,5 @@ set(INCLUDE_DIR include_directories(${INCLUDE_DIR}) -add_library(${LINK_SDK_NAME} SHARED ${LIB_SRC}) \ No newline at end of file +add_library(${LINK_SDK_NAME} SHARED ${LIB_SRC}) +add_library(${LINK_SDK_NAME} STATIC ${LIB_SRC}) -- Gitee From d5e96c292b3b56339eb565450dc58b87c3e02f10 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 22:11:50 +0800 Subject: [PATCH 22/34] =?UTF-8?q?=E5=88=A0=E9=99=A4check.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/include/check.h | 2366 --------------------------------- 1 file changed, 2366 deletions(-) delete mode 100644 yonglin_zhang/include/check.h diff --git a/yonglin_zhang/include/check.h b/yonglin_zhang/include/check.h deleted file mode 100644 index 497f0ea..0000000 --- a/yonglin_zhang/include/check.h +++ /dev/null @@ -1,2366 +0,0 @@ -/*-*- mode:C; -*- */ -/* - * Check: a unit test framework for C - * Copyright (C) 2001, 2002 Arien Malec - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#ifndef CHECK_H -#define CHECK_H - -#include -#include -#include -#include - -#include - -/* - Macros and functions starting with _ (underscore) are internal and - may change without notice. You have been warned!. -*/ - - -#ifdef __cplusplus -#define CK_CPPSTART extern "C" { -#define CK_CPPEND } -CK_CPPSTART -#endif - -/** - * __GNUC_PATCHLEVEL__ is new to GCC 3.0; - * it is also present in the widely-used development snapshots leading up to 3.0 - * (which identify themselves as GCC 2.96 or 2.97, depending on which snapshot you have). - * - * https://stackoverflow.com/questions/1936719/what-are-the-gcc-predefined-macros-for-the-compilers-version-number/1936745#1936745 - */ - -#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) -#define GCC_VERSION_AT_LEAST(major, minor, patch) \ -((__GNUC__ > (major)) || \ - (__GNUC__ == (major) && __GNUC_MINOR__ > (minor)) || \ - (__GNUC__ == (major) && __GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patch)) ) -#elif defined(__GNUC__) && defined(__GNUC_MINOR__) -#define GCC_VERSION_AT_LEAST(major, minor, patch) \ -((__GNUC__ > (major)) || \ - (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) -#else -#define GCC_VERSION_AT_LEAST(major, minor, patch) 0 -#endif - -#if GCC_VERSION_AT_LEAST(2,95,3) -#define CK_ATTRIBUTE_UNUSED __attribute__ ((unused)) -#define CK_ATTRIBUTE_FORMAT(a, b, c) __attribute__ ((format (a, b, c))) -#else -#define CK_ATTRIBUTE_UNUSED -#define CK_ATTRIBUTE_FORMAT(a, b, c) -#endif /* GCC 2.95 */ - -#if GCC_VERSION_AT_LEAST(2,5,0) -#define CK_ATTRIBUTE_NORETURN __attribute__ ((noreturn)) -#else -#define CK_ATTRIBUTE_NORETURN -#endif /* GCC 2.5 */ - -#if GCC_VERSION_AT_LEAST(4,7,4) && (__STDC_VERSION__ >= 199901L) -/* Operator _Pragma introduced in C99 */ -#define CK_DIAGNOSTIC_STRINGIFY(x) #x -#define CK_DIAGNOSTIC_HELPER1(y) CK_DIAGNOSTIC_STRINGIFY(GCC diagnostic ignored y) -#define CK_DIAGNOSTIC_HELPER2(z) CK_DIAGNOSTIC_HELPER1(#z) -#define CK_DIAGNOSTIC_PUSH_IGNORE(w) \ - _Pragma("GCC diagnostic push") \ - _Pragma(CK_DIAGNOSTIC_HELPER2(w)) -#define CK_DIAGNOSTIC_POP(w) _Pragma ("GCC diagnostic pop") -#else -#define CK_DIAGNOSTIC_PUSH_IGNORE(w) -#define CK_DIAGNOSTIC_POP(w) -#endif /* GCC 4.7.4 */ - -#undef GCC_VERSION_AT_LEAST - -#include - -#if defined(_MSC_VER) -/* define pid_t for Windows, as it is needed later */ -#define pid_t int -#endif /* _MSC_VER */ - -/* - * Used to create the linker script for hiding lib-local symbols. Shall - * be put directly in front of the exported symbol. - */ -#define CK_EXPORT - -/* - * Used for MSVC to create the export attribute - * CK_DLL_EXP is defined during the compilation of the library - * on the command line. - * - * This definition is only used when building or linking to - * the shared library, i.e. libcheck.so. When building the library - * the value must be "_declspec(dllexport)". - * When linking with the library, the value must be "_declspec(dllimport)" - * - * This is only used with Microsoft Visual C. In other systems - * the value is empty. In MSVC the value is empty when linking with - * a static library. - */ -#ifndef CK_DLL_EXP -#define CK_DLL_EXP -#endif - -/* check version numbers */ - -#define CHECK_MAJOR_VERSION (0) -#define CHECK_MINOR_VERSION (15) -#define CHECK_MICRO_VERSION (2) - -CK_DLL_EXP extern int CK_EXPORT check_major_version; -CK_DLL_EXP extern int CK_EXPORT check_minor_version; -CK_DLL_EXP extern int CK_EXPORT check_micro_version; - -#ifndef NULL -#define NULL ((void*)0) -#endif - -/** - * Type for a test case - * - * A TCase represents a test case. Create with tcase_create, free - * with tcase_free. For the moment, test cases can only be run - * through a suite -*/ -typedef struct TCase TCase; - -/** - * Type for a test function - */ -typedef void (*TFun) (int); - -/** - * Type for a setup/teardown function - */ -typedef void (*SFun) (void); - -/** - * Type for a test suite - */ -typedef struct Suite Suite; - -/** - * Type for a test, which wraps a test function - */ -typedef struct TTest { - const char *name; - TFun fn; - const char *file; - int line; -} TTest; - -/** - * Creates a test suite with the given name. - * - * Create a suite, which will contain test cases. Once - * created, use suite_add_tcase() to add test cases. - * When finished, create a suite runner from the - * suite using srunner_create() - * - * @param name name of the suite - * - * @return suite - * - * @since 0.6.0 - */ -CK_DLL_EXP Suite *CK_EXPORT suite_create(const char *name); - -/** - * Determines whether a given test suite contains a case named after a - * given string. - * - * @param s suite to check - * @param tcname test case to look for - * - * @return 1 iff the given test case is within the given suite; - * 0 otherwise - * - * @since 0.9.9 - */ -CK_DLL_EXP int CK_EXPORT suite_tcase(Suite * s, const char *tcname); - -/** - * Add a test case to a suite. - * - * Note that if the TCase has already been added attempting - * to add it again will be ignored. - * - * @param s suite to add test case to - * @param tc test case to add to suite - * - * @since 0.6.0 - */ -CK_DLL_EXP void CK_EXPORT suite_add_tcase(Suite * s, TCase * tc); - -/** - * Create a test case. - * - * Once created, tests can be added with the tcase_add_test() - * function, and the test case assigned to a suite with the - * suite_add_tcase() function. - * - * @param name name of the test case - * - * @return test case containing no tests - * - * @since 0.6.0 - * */ -CK_DLL_EXP TCase *CK_EXPORT tcase_create(const char *name); - -/** - * Associate a test case with certain tags. - * Replaces any existing tags with the new set. - * - * @param tc the test case - * - * @param tags string containing arbitrary tags separated by spaces. - * This will be copied. Passing NULL clears all tags. - * - * @since 0.11.0 - * */ -CK_DLL_EXP void CK_EXPORT tcase_set_tags(TCase * tc, - const char *tags); -/** - * Add a test function to a test case - * - * @param tc test case to add test to - * @param tf test function to add to test case - * - * @since 0.6.0 - * */ -#define tcase_add_test(tc,tf) tcase_add_test_raise_signal(tc,tf,0) - -/** - * Add a test function with signal handling to a test case - * - * The added test is expected to terminate by throwing the given signal - * - * @param tc test case to add test to - * @param tf test function to add to test case - * @param signal expected signal for test function to throw in order for - * the test to be considered passing - * - * @since 0.9.2 - * */ -#define tcase_add_test_raise_signal(tc,ttest,signal) \ - _tcase_add_test((tc),(ttest),(signal), 0, 0, 1) - -/** - * Add a test function with an expected exit value to a test case - * - * The added test is expected to terminate by exiting with the given value - * - * @param tc test case to add test to - * @param tf test function to add to test case - * @param expected_exit_value exit value for test function to return in - * order for the test to be considered passing - * - * @since 0.9.7 - */ -#define tcase_add_exit_test(tc, ttest, expected_exit_value) \ - _tcase_add_test((tc),(ttest),0,(expected_exit_value),0,1) - -/** - * Add a looping test function to a test case - * - * The test will be called in a for(i = s; i < e; i++) loop with each - * iteration being executed in a new context. The loop variable 'i' is - * available in the test. - * - * @param tc test case to add test to - * @param tf function to add to test case - * @param s starting index for value "i" in test - * @param e ending index for value "i" in test - * - * @since 0.9.4 - */ -#define tcase_add_loop_test(tc,ttest,s,e) \ - _tcase_add_test((tc),(ttest),0,0,(s),(e)) - -/** - * Add a looping test function with signal handling to a test case - * - * The test will be called in a for(i = s; i < e; i++) loop with each - * iteration being executed in a new context. The loop variable 'i' is - * available in the test. - * - * The added test is expected to terminate by throwing the given signal - * - * @param tc test case to add test to - * @param tf function to add to test case - * @param signal expected signal for test function to throw in order for - * the test to be considered passing - * @param s starting index for value "i" in test - * @param e ending index for value "i" in test - * - * @since 0.9.5 - */ -#define tcase_add_loop_test_raise_signal(tc,ttest,signal,s,e) \ - _tcase_add_test((tc),(ttest),(signal),0,(s),(e)) - -/** - * Add a looping test function with an expected exit value to a test case - * - * The test will be called in a for(i = s; i < e; i++) loop with each - * iteration being executed in a new context. The loop variable 'i' is - * available in the test. - * - * The added test is expected to terminate by exiting with the given value - * - * @param tc test case to add test to - * @param tf function to add to test case - * @param expected_exit_value exit value for test function to return in - * order for the test to be considered passing - * @param s starting index for value "i" in test - * @param e ending index for value "i" in test - * - * @since 0.9.7 - */ -#define tcase_add_loop_exit_test(tc,ttest,expected_exit_value,s,e) \ - _tcase_add_test((tc),(ttest),0,(expected_exit_value),(s),(e)) - -/* Add a test function to a test case - (function version -- use this when the macro won't work -*/ -CK_DLL_EXP void CK_EXPORT _tcase_add_test(TCase * tc, const TTest * ttest, - int _signal, int allowed_exit_value, - int start, int end); - -/** - * Add unchecked fixture setup/teardown functions to a test case - * - * Unchecked fixture functions are run at the start and end of the - * test case, and not before and after unit tests. Further, - * unchecked fixture functions are not run in a separate address space, - * like test functions, and so must not exit or signal (e.g., - * segfault). - * - * Also, when run in CK_NOFORK mode, unchecked fixture functions may - * lead to different unit test behavior if unit tests change data - * setup by the fixture functions. - * - * Note that if a setup function fails, the remaining setup functions - * will be omitted, as will the test case and the teardown functions. - * If a teardown function fails the remaining teardown functins will be - * omitted. - * - * @param tc test case to add unchecked fixture setup/teardown to - * @param setup function to add to be executed before the test case; - * if NULL no setup function is added - * @param teardown function to add to be executed after the test case; - * if NULL no teardown function is added - * @since 0.8.0 - */ -CK_DLL_EXP void CK_EXPORT tcase_add_unchecked_fixture(TCase * tc, SFun setup, - SFun teardown); - -/** - * Add checked fixture setup/teardown functions to a test case - * - * Checked fixture functions are run before and after each unit test inside - * of the address space of the test. Thus, if using CK_FORK - * mode the separate process running the unit test will survive signals - * or unexpected exits in the fixture function. Also, if the setup - * function is idempotent, unit test behavior will be the same in - * CK_FORK and CK_NOFORK modes. - * - * However, since fixture functions are run before and after each unit - * test, they should not be expensive code. - * - * Note that if a setup function fails, the remaining setup functions - * will be omitted, as will the test and the teardown functions. If a - * teardown function fails the remaining teardown functins will be - * omitted. - * - * @param tc test case to add checked fixture setup/teardown to - * @param setup function to add to be executed before each unit test in - * the test case; if NULL no setup function is added - * @param teardown function to add to be executed after each unit test in - * the test case; if NULL no teardown function is added - * - * @since 0.8.0 -*/ -CK_DLL_EXP void CK_EXPORT tcase_add_checked_fixture(TCase * tc, SFun setup, - SFun teardown); - -/** - * Set the timeout for all tests in a test case. - * - * A test that lasts longer than the timeout (in seconds) will be killed - * and thus fail with an error. - * - * If not set, the default timeout is one assigned at compile time. If - * the environment variable CK_DEFAULT_TIMEOUT is defined and no timeout - * is set, the value in the environment variable is used. - * - * If Check is compile without fork() support this call is ignored, - * as timeouts are not possible. - * - * @param tc test case to assign timeout to - * @param timeout to use, in seconds. If the value contains a decimal - * portion, but no high resolution timer is available, - * the value is rounded up to the nearest second. - * - * @since 0.9.2 - */ -CK_DLL_EXP void CK_EXPORT tcase_set_timeout(TCase * tc, double timeout); - -/* Internal function to mark the start of a test function */ -CK_DLL_EXP void CK_EXPORT tcase_fn_start(const char *fname, const char *file, - int line); - -/** - * Retreive the name of the current running test. This is the name - * of the test passed to START_TEST. This is only valid when called - * from a running test. The value return outside of a running test is - * undefined. - * - * @since 0.11.0 - */ -CK_DLL_EXP const char* CK_EXPORT tcase_name(void); - -/** - * Start a unit test with START_TEST(unit_name), end with END_TEST. - * - * One must use braces within a START_/END_ pair to declare new variables - * - * @since 0.6.0 - */ -#define START_TEST(__testname)\ -static void __testname ## _fn (int _i CK_ATTRIBUTE_UNUSED);\ -static const TTest __testname ## _ttest = {""# __testname, __testname ## _fn, __FILE__, __LINE__};\ -static const TTest * __testname = & __testname ## _ttest;\ -static void __testname ## _fn (int _i CK_ATTRIBUTE_UNUSED) - -/** - * End a unit test - * - * @since 0.6.0 - */ -#define END_TEST - -/* - * Fail the test case unless expr is false - * - * This call is deprecated. - */ -#define fail_unless(expr, ...) \ - (expr) ? \ - _mark_point(__FILE__, __LINE__) : \ - _ck_assert_failed(__FILE__, __LINE__, "Assertion '"#expr"' failed" , ## __VA_ARGS__, NULL) - -/* - * Fail the test case if expr is false - * - * This call is deprecated. - * - * NOTE: The space before the comma sign before ## is essential to be compatible - * with gcc 2.95.3 and earlier. - * FIXME: these macros may conflict with C89 if expr is - * FIXME: strcmp (str1, str2) due to excessive string length. - */ -#define fail_if(expr, ...)\ - (expr) ? \ - _ck_assert_failed(__FILE__, __LINE__, "Failure '"#expr"' occurred" , ## __VA_ARGS__, NULL) \ - : _mark_point(__FILE__, __LINE__) - -/* - * Fail the test - * - * This call is deprecated. - */ -#define fail(...) _ck_assert_failed(__FILE__, __LINE__, "Failed" , ## __VA_ARGS__, NULL) - -/* - * This is called whenever an assertion fails. - * Note that it only has the noreturn modifier when - * using fork. If fork is unavailable, the function - * calls longjmp() when a test assertion fails. Marking - * the function as noreturn causes gcc to make assumptions - * which are not valid, as longjmp() is like a return. - */ -#if 0 -CK_DLL_EXP void CK_EXPORT _ck_assert_failed(const char *file, int line, - const char *expr, const char *msg, - ...) CK_ATTRIBUTE_NORETURN CK_ATTRIBUTE_FORMAT(printf, 4, 5); -#else -CK_DLL_EXP void CK_EXPORT _ck_assert_failed(const char *file, int line, - const char *expr, const char *msg, - ...) CK_ATTRIBUTE_FORMAT(printf, 4, 5); -#endif - -/** - * Fail the test if expression is false - * - * @param expr expression to evaluate - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.6 - */ -#define ck_assert(expr) ck_assert_msg(expr, NULL) - -/* The space before the comma sign before ## is essential to be compatible - with gcc 2.95.3 and earlier. -*/ -/** - * Fail the test if the expression is false; print message on failure - * - * @param expr expression to evaluate - * @param ... message to print (in printf format) if expression is false - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.6 - */ -#define ck_assert_msg(expr, ...) \ - (expr) ? \ - _mark_point(__FILE__, __LINE__) : \ - _ck_assert_failed(__FILE__, __LINE__, "Assertion '"#expr"' failed" , ## __VA_ARGS__) - -/** - * Unconditionally fail the test - * - * @note Once called, the remaining of the test is aborted - * - * @since 0.9.6 - */ -#define ck_abort() ck_abort_msg(NULL) -/** - * Unconditionally fail the test; print a message - * - * @param ... message to print (in printf format) - * - * @note Once called, the remaining of the test is aborted - * - * @since 0.9.6 - */ -#define ck_abort_msg(...) _ck_assert_failed(__FILE__, __LINE__, "Failed" , ## __VA_ARGS__) - -/* Signed and unsigned integer comparison macros with improved output compared to ck_assert(). */ -/* OP may be any comparison operator. */ -#define _ck_assert_int(X, OP, Y) do { \ - intmax_t _ck_x = (X); \ - intmax_t _ck_y = (Y); \ - ck_assert_msg(_ck_x OP _ck_y, "Assertion '%s' failed: %s == %jd, %s == %jd", #X" "#OP" "#Y, #X, _ck_x, #Y, _ck_y); \ -} while (0) - -/** - * Check two signed integers to determine if X==Y - * - * If not X==Y, the test fails. - * - * @param X signed integer - * @param Y signed integer to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.6 - */ -#define ck_assert_int_eq(X, Y) _ck_assert_int(X, ==, Y) -/** - * Check two signed integers to determine if X!=Y - * - * If not X!=Y, the test fails. - * - * @param X signed integer - * @param Y signed integer to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.6 - */ -#define ck_assert_int_ne(X, Y) _ck_assert_int(X, !=, Y) -/** - * Check two signed integers to determine if XY - * - * If not X>Y, the test fails. - * - * @param X signed integer - * @param Y signed integer to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.10 - */ -#define ck_assert_int_gt(X, Y) _ck_assert_int(X, >, Y) -/** - * Check two signed integers to determine if X>=Y - * - * If not X>=Y, the test fails. - * - * @param X signed integer - * @param Y signed integer to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.10 - */ -#define ck_assert_int_ge(X, Y) _ck_assert_int(X, >=, Y) - -#define _ck_assert_uint(X, OP, Y) do { \ - uintmax_t _ck_x = (X); \ - uintmax_t _ck_y = (Y); \ - ck_assert_msg(_ck_x OP _ck_y, "Assertion '%s' failed: %s == %ju, %s == %ju", #X" "#OP" "#Y, #X, _ck_x, #Y, _ck_y); \ -} while (0) -/** - * Check two unsigned integers to determine if X==Y - * - * If not X==Y, the test fails. - * - * @param X signed integer - * @param Y signed integer to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.10 - */ -#define ck_assert_uint_eq(X, Y) _ck_assert_uint(X, ==, Y) -/** - * Check two unsigned integers to determine if X!=Y - * - * If not X!=Y, the test fails. - * - * @param X signed integer - * @param Y signed integer to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.10 - */ -#define ck_assert_uint_ne(X, Y) _ck_assert_uint(X, !=, Y) -/** - * Check two unsigned integers to determine if XY - * - * If not X>Y, the test fails. - * - * @param X signed integer - * @param Y signed integer to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.10 - */ -#define ck_assert_uint_gt(X, Y) _ck_assert_uint(X, >, Y) -/** - * Check two unsigned integers to determine if X>=Y - * - * If not X>=Y, the test fails. - * - * @param X signed integer - * @param Y signed integer to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.10 - */ -#define ck_assert_uint_ge(X, Y) _ck_assert_uint(X, >=, Y) - -/* Number of digits after the decimal point to output via printf */ -#ifndef CK_FLOATING_DIG -# define CK_FLOATING_DIG 6 -#endif /* CK_FLOATING_DIG */ - -/* Floating point number comparison macros with improved output - * compared to ck_assert(). */ -/* OP may be any comparison operator, TP is type, TM is type modifier. */ -#define _ck_assert_floating(X, OP, Y, TP, TM) do { \ - TP _ck_x = (X); \ - TP _ck_y = (Y); \ - ck_assert_msg(_ck_x OP _ck_y, \ - "Assertion '%s' failed: %s == %.*" TM "g, %s == %.*" TM "g", \ - #X" "#OP" "#Y, \ - #X, (int)CK_FLOATING_DIG, _ck_x, \ - #Y, (int)CK_FLOATING_DIG, _ck_y); \ -} while (0) - -/* Check floating point number is finise. */ -/* TP is type, TM is type modifier. */ -#define _ck_assert_floating_finite(X, TP, TM) \ -do { \ - TP _ck_x = (X); \ - ck_assert_msg(isfinite(_ck_x), \ - "Assertion '%s' failed: %s == %.*" TM "g", \ - #X" is finite", \ - #X, (int)CK_FLOATING_DIG, _ck_x); \ -} while (0) - -/* Check floating point number is infinise. */ -/* TP is type, TM is type modifier. */ -#define _ck_assert_floating_infinite(X, TP, TM) \ -do { \ - TP _ck_x = (X); \ - ck_assert_msg(isinf(_ck_x), \ - "Assertion '%s' failed: %s == %.*" TM "g", \ - #X" is infinite", \ - #X, (int)CK_FLOATING_DIG, _ck_x); \ -} while (0) - -/* Check floating point number is "Not a Number". */ -/* TP is type, TM is type modifier. */ -#define _ck_assert_floating_nan(X, TP, TM) \ -do { \ - TP _ck_x = (X); \ - ck_assert_msg(isnan(_ck_x), \ - "Assertion '%s' failed: %s == %.*" TM "g", \ - #X" is NaN", \ - #X, (int)CK_FLOATING_DIG, _ck_x); \ -} while (0) - -/* Check floating point number is not "Not a Number". */ -/* TP is type, TM is type modifier. */ -#define _ck_assert_floating_nonnan(X, TP, TM) \ -do { \ - TP _ck_x = (X); \ - ck_assert_msg(!isnan(_ck_x), \ - "Assertion '%s' failed: %s == %.*" TM "g", \ - #X" is not NaN", \ - #X, (int)CK_FLOATING_DIG, _ck_x); \ -} while (0) - -/* Floating point tolerance comparison macros with improved output - * compared to ck_assert(). */ -/* OP, D can have values: >, -1; <, 1. */ -#define _ck_assert_floating_op_tol(X, OP, Y, T, D, TP, TM) do { \ - TP _ck_x = (X); \ - TP _ck_y = (Y); \ - TP _ck_t = (T); \ - ck_assert_msg((_ck_x - _ck_y) OP _ck_t * (D), \ - "Assertion '%s' failed: %s == %.*" TM "g, %s == %.*" TM "g, %s == %.*" TM "g", \ - #X" "#OP"= "#Y", error < "#T, \ - #X, (int)CK_FLOATING_DIG, _ck_x, \ - #Y, (int)CK_FLOATING_DIG, _ck_y, \ - #T, (int)CK_FLOATING_DIG, _ck_t); \ -} while (0) - -/* Floating point tolerance comparison macros with improved output - * compared to ck_assert(). */ -/* OP can have values: <; >=. */ -#define _ck_assert_floating_absdiff_op_tol(X, Y, OP, T, TP, TM) \ -do { \ - TP _ck_x = (X); \ - TP _ck_y = (Y); \ - TP _ck_t = (T); \ - ck_assert_msg(fabsl(_ck_y - _ck_x) OP _ck_t, \ - "Assertion '%s' failed: %s == %.*" TM "g, %s == %.*" TM "g, %s == %.*" TM "g", \ - "fabsl("#Y" - "#X") "#OP" "#T, \ - #X, (int)CK_FLOATING_DIG, _ck_x, \ - #Y, (int)CK_FLOATING_DIG, _ck_y, \ - #T, (int)CK_FLOATING_DIG, _ck_t); \ -} while (0) - -/** - * Check two single precision floating point numbers to determine if X == Y. - * - * Note that the usefulness of this assertion is very limited. If you - * want to compare two floating point numbers for equality, you probably - * want to use ck_assert_float_eq_tol instead. - * - * If not X == Y, the test fails. - * - * @param X floating point number (float) - * @param Y floating point number (float) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_eq(X, Y) _ck_assert_floating(X, ==, Y, float, "") -/** - * Check two single precision floating point numbers to determine if X != Y. - * - * Note that the usefulness of this assertion is very limited. If you - * want to compare two floating point numbers for equality, you probably - * want to use ck_assert_float_ne_tol instead. - * - * If not X != Y, the test fails. - * - * @param X floating point number (float) - * @param Y floating point number (float) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_ne(X, Y) _ck_assert_floating(X, !=, Y, float, "") -/** - * Check two single precision floating point numbers to determine if X < Y - * - * If not X < Y, the test fails. - * - * @param X floating point number (float) - * @param Y floating point number (float) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_lt(X, Y) _ck_assert_floating(X, <, Y, float, "") -/** - * Check two single precision floating point numbers to determine if X <= Y - * - * If not X <= Y, the test fails. - * - * @param X floating point number (float) - * @param Y floating point number (float) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_le(X, Y) _ck_assert_floating(X, <=, Y, float, "") -/** - * Check two single precision floating point numbers to determine if X > Y - * - * If not X > Y, the test fails. - * - * @param X floating point number (float) - * @param Y floating point number (float) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_gt(X, Y) _ck_assert_floating(X, >, Y, float, "") -/** - * Check two single precision floating point numbers to determine if X >= Y - * - * If not X >= Y, the test fails. - * - * @param X floating point number (float) - * @param Y floating point number (float) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_ge(X, Y) _ck_assert_floating(X, >=, Y, float, "") - -/** - * Check two single precision floating point numbers to determine if X≈Y - * with specified tolerance - * - * If not X ≈ Y with error < T, the test fails. - * - * @param X floating point number (float) - * @param Y floating point number (float) to compare against X - * @param T tolerance (float) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_eq_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, <, T, float, "") - -/** - * Check two single precision floating point numbers to determine if not X≈Y - * with specified tolerance - * - * If X ≈ Y with error < T, the test fails. - * - * @param X floating point number (float) - * @param Y floating point number (float) to compare against X - * @param T tolerance (float) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_ne_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, >=, T, float, "") - -/** - * Check two single precision floating point numbers to determine if X>≈Y - * with specified tolerance - * - * If not X >≈ Y with error < T, the test fails. - * - * @param X floating point number (float) - * @param Y floating point number (float) to compare against X - * @param T tolerance (float) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_ge_tol(X, Y, T) _ck_assert_floating_op_tol(X, >, Y, T, -1, float, "") - -/** - * Check two single precision floating point numbers to determine if X<≈Y - * with specified tolerance - * - * If not X <≈ Y with error < T, the test fails. - * - * @param X floating point number (float) - * @param Y floating point number (float) to compare against X - * @param T tolerance (float) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_le_tol(X, Y, T) _ck_assert_floating_op_tol(X, <, Y, T, 1, float, "") - -/** - * Check that a single precision floating point number is finite; i.e. is - * not +infinity, -infinity, or "Not a Number" (NaN) - * - * If X is +INFINITY or X is -INFINITY, or X is NaN, the test fails. - * - * @param X floating point number (float) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_finite(X) _ck_assert_floating_finite(X, float, "") - -/** - * Check that a single precision floating point number is infinite, - * either +infinity or -infinity - * - * If X is not +INFINITY and X is not -INFINITY, the test fails. - * - * @param X floating point number (float) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_infinite(X) _ck_assert_floating_infinite(X, float, "") - -/** - * Check that a single precision floating point number - * is "Not a Number" (NaN) - * - * If X is not NaN, the test fails. - * - * @param X floating point number (float) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_nan(X) _ck_assert_floating_nan(X, float, "") - -/** - * Check that a single precision floating point number is - * not "Not a Number" (NaN) - * - * If X is NaN, the test fails. - * - * @param X floating point number (float) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_float_nonnan(X) _ck_assert_floating_nonnan(X, float, "") - -/** - * Check two double precision floating point numbers to determine if X == Y. - * - * Note that the usefulness of this assertion is very limited. If you - * want to compare two floating point numbers for equality, you probably - * want to use ck_assert_double_eq_tol instead. - * - * If not X == Y, the test fails. - * - * @param X floating point number (double) - * @param Y floating point number (double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_eq(X, Y) _ck_assert_floating(X, ==, Y, double, "") -/** - * Check two double precision floating point numbers to determine if X != Y. - * - * Note that the usefulness of this assertion is very limited. If you - * want to compare two floating point numbers for equality, you probably - * want to use ck_assert_double_ne_tol instead. - * - * If not X != Y, the test fails. - * - * @param X floating point number (double) - * @param Y floating point number (double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_ne(X, Y) _ck_assert_floating(X, !=, Y, double, "") -/** - * Check two double precision floating point numbers to determine if X < Y - * - * If not X < Y, the test fails. - * - * @param X floating point number (double) - * @param Y floating point number (double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_lt(X, Y) _ck_assert_floating(X, <, Y, double, "") -/** - * Check two double precision floating point numbers to determine if X <= Y - * - * If not X <= Y, the test fails. - * - * @param X floating point number (double) - * @param Y floating point number (double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_le(X, Y) _ck_assert_floating(X, <=, Y, double, "") -/** - * Check two double precision floating point numbers to determine if X > Y - * - * If not X > Y, the test fails. - * - * @param X floating point number (double) - * @param Y floating point number (double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_gt(X, Y) _ck_assert_floating(X, >, Y, double, "") -/** - * Check two double precision floating point numbers to determine if X >= Y - * - * If not X >= Y, the test fails. - * - * @param X floating point number (double) - * @param Y floating point number (double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_ge(X, Y) _ck_assert_floating(X, >=, Y, double, "") - -/** - * Check two double precision floating point numbers to determine if X≈Y - * with specified tolerance - * - * If not X ≈ Y with error < T, the test fails. - * - * @param X floating point number (double) - * @param Y floating point number (double) to compare against X - * @param T tolerance (double) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_eq_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, <, T, double, "") - -/** - * Check two double precision floating point numbers to determine if not X≈Y - * with specified tolerance - * - * If X ≈ Y with error < T, the test fails. - * - * @param X floating point number (double) - * @param Y floating point number (double) to compare against X - * @param T tolerance (double) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_ne_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, >=, T, double, "") - -/** - * Check two double precision floating point numbers to determine if X>≈Y - * with specified tolerance - * - * If not X >≈ Y with error < T, the test fails. - * - * @param X floating point number (double) - * @param Y floating point number (double) to compare against X - * @param T tolerance (double) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_ge_tol(X, Y, T) _ck_assert_floating_op_tol(X, >, Y, T, -1, double, "") - -/** - * Check two double precision floating point numbers to determine if X<≈Y - * with specified tolerance - * - * If not X <≈ Y with error < T, the test fails. - * - * @param X floating point number (double) - * @param Y floating point number (double) to compare against X - * @param T tolerance (double) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_le_tol(X, Y, T) _ck_assert_floating_op_tol(X, <, Y, T, 1, double, "") - -/** - * Check that a double precision floating point number is finite; i.e. is - * not +infinity, -infinity, or "Not a Number" (NaN) - * - * If X is +INFINITY or X is -INFINITY, or X is NaN, the test fails. - * - * @param X floating point number (double) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_finite(X) _ck_assert_floating_finite(X, double, "") - -/** - * Check that a double precision floating point number is infinite, - * either +infinity or -infinity - * - * If X is not +INFINITY and X is not -INFINITY, the test fails. - * - * @param X floating point number (double) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_infinite(X) _ck_assert_floating_infinite(X, double, "") - -/** - * Check that a double precision floating point number - * is "Not a Number" (NaN) - * - * If X is not NaN, the test fails. - * - * @param X floating point number (double) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_nan(X) _ck_assert_floating_nan(X, double, "") - -/** - * Check that a double precision floating point number is - * not "Not a Number" (NaN) - * - * If X is NaN, the test fails. - * - * @param X floating point number (double) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_double_nonnan(X) _ck_assert_floating_nonnan(X, double, "") - -/** - * Check two double precision floating point numbers to determine if X == Y. - * - * Note that the usefulness of this assertion is very limited. If you - * want to compare two floating point numbers for equality, you probably - * want to use ck_assert_ldouble_eq_tol instead. - * - * If not X == Y, the test fails. - * - * @param X floating point number (long double) - * @param Y floating point number (long double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_eq(X, Y) _ck_assert_floating(X, ==, Y, long double, "L") -/** - * Check two double precision floating point numbers to determine if X != Y. - * - * Note that the usefulness of this assertion is very limited. If you - * want to compare two floating point numbers for equality, you probably - * want to use ck_assert_ldouble_ne_tol instead. - * - * If not X != Y, the test fails. - * - * @param X floating point number (long double) - * @param Y floating point number (long double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_ne(X, Y) _ck_assert_floating(X, !=, Y, long double, "L") -/** - * Check two double precision floating point numbers to determine if X < Y - * - * If not X < Y, the test fails. - * - * @param X floating point number (long double) - * @param Y floating point number (long double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_lt(X, Y) _ck_assert_floating(X, <, Y, long double, "L") -/** - * Check two double precision floating point numbers to determine if X <= Y - * - * If not X <= Y, the test fails. - * - * @param X floating point number (long double) - * @param Y floating point number (long double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_le(X, Y) _ck_assert_floating(X, <=, Y, long double, "L") -/** - * Check two double precision floating point numbers to determine if X > Y - * - * If not X > Y, the test fails. - * - * @param X floating point number (long double) - * @param Y floating point number (long double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_gt(X, Y) _ck_assert_floating(X, >, Y, long double, "L") -/** - * Check two double precision floating point numbers to determine if X >= Y - * - * If not X >= Y, the test fails. - * - * @param X floating point number (long double) - * @param Y floating point number (long double) to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_ge(X, Y) _ck_assert_floating(X, >=, Y, long double, "L") - -/** - * Check two double precision floating point numbers to determine if X≈Y - * with specified tolerance - * - * If not X ≈ Y with error < T, the test fails. - * - * @param X floating point number (long double) - * @param Y floating point number (long double) to compare against X - * @param T tolerance (long double) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_eq_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, <, T, long double, "L") - -/** - * Check two double precision floating point numbers to determine if not X≈Y - * with specified tolerance - * - * If X ≈ Y with error < T, the test fails. - * - * @param X floating point number (long double) - * @param Y floating point number (long double) to compare against X - * @param T tolerance (long double) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_ne_tol(X, Y, T) _ck_assert_floating_absdiff_op_tol(X, Y, >=, T, long double, "L") - -/** - * Check two double precision floating point numbers to determine if X>≈Y - * with specified tolerance - * - * If not X >≈ Y with error < T, the test fails. - * - * @param X floating point number (long double) - * @param Y floating point number (long double) to compare against X - * @param T tolerance (long double) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_ge_tol(X, Y, T) _ck_assert_floating_op_tol(X, >, Y, T, -1, long double, "L") - -/** - * Check two double precision floating point numbers to determine if X<≈Y - * with specified tolerance - * - * If not X <≈ Y with error < T, the test fails. - * - * @param X floating point number (long double) - * @param Y floating point number (long double) to compare against X - * @param T tolerance (long double) - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_le_tol(X, Y, T) _ck_assert_floating_op_tol(X, <, Y, T, 1, long double, "L") - -/** - * Check that a double precision floating point number is finite; i.e. is - * not +infinity, -infinity, or "Not a Number" (NaN) - * - * If X is +INFINITY or X is -INFINITY, or X is NaN, the test fails. - * - * @param X floating point number (long double) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_finite(X) _ck_assert_floating_finite(X, long double, "L") - -/** - * Check that a double precision floating point number is infinite, - * either +infinity or -infinity - * - * If X is not +INFINITY and X is not -INFINITY, the test fails. - * - * @param X floating point number (long double) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_infinite(X) _ck_assert_floating_infinite(X, long double, "L") - -/** - * Check that a double precision floating point number - * is "Not a Number" (NaN) - * - * If X is not NaN, the test fails. - * - * @param X floating point number (long double) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_nan(X) _ck_assert_floating_nan(X, long double, "L") - -/** - * Check that a double precision floating point number is - * not "Not a Number" (NaN) - * - * If X is NaN, the test fails. - * - * @param X floating point number (long double) to be checked - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ldouble_nonnan(X) _ck_assert_floating_nonnan(X, long double, "L") - -/* String comparison macros with improved output compared to ck_assert() */ -/* OP might be any operator that can be used in '0 OP strcmp(X,Y)' comparison. */ -/* String pointer could be compared againts NULL with == (NULLEQ = 1) and != (NULLNE = 1) operators. */ -/* The x and y parameter swap in strcmp() is needed to handle >, >=, <, <= operators. */ -/* If the x or y parameter is NULL its value will be printed without quotes. */ -#define _ck_assert_str(X, OP, Y, NULLEQ, NULLNE) do { \ - const char* _ck_x = (X); \ - const char* _ck_y = (Y); \ - const char* _ck_x_s; \ - const char* _ck_y_s; \ - const char* _ck_x_q; \ - const char* _ck_y_q; \ - if (_ck_x != NULL) { \ - _ck_x_q = "\""; \ - _ck_x_s = _ck_x; \ - } else { \ - _ck_x_q = ""; \ - _ck_x_s = "(null)"; \ - } \ - if (_ck_y != NULL) { \ - _ck_y_q = "\""; \ - _ck_y_s = _ck_y; \ - } else { \ - _ck_y_q = ""; \ - _ck_y_s = "(null)"; \ - } \ - ck_assert_msg( \ - (NULLEQ && (_ck_x == NULL) && (_ck_y == NULL)) || \ - (NULLNE && ((_ck_x == NULL) || (_ck_y == NULL)) && (_ck_x != _ck_y)) || \ - ((_ck_x != NULL) && (_ck_y != NULL) && (0 OP strcmp(_ck_y, _ck_x))), \ - "Assertion '%s' failed: %s == %s%s%s, %s == %s%s%s", \ - #X" "#OP" "#Y, \ - #X, _ck_x_q, _ck_x_s, _ck_x_q, \ - #Y, _ck_y_q, _ck_y_s, _ck_y_q); \ -} while (0) - -/** - * Check two strings to determine if 0==strcmp(X,Y) - * - * If X or Y is NULL the test fails. - * If not 0==strcmp(X,Y), the test fails. - * - * @param X string - * @param Y string to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.6 - */ -#define ck_assert_str_eq(X, Y) _ck_assert_str(X, ==, Y, 0, 0) - -/** - * Check two strings to determine if 0!=strcmp(X,Y) - * - * If X or Y is NULL the test fails. - * If not 0!=strcmp(X,Y), the test fails. - * - * @param X string - * @param Y string to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.6 - */ -#define ck_assert_str_ne(X, Y) _ck_assert_str(X, !=, Y, 0, 0) - -/** - * Check two strings to determine if 00) - * - * If X or Y is NULL the test fails. - * If not 0=0) - * - * If X or Y is NULL the test fails. - * If not 0<=strcmp(X,Y), the test fails. - * - * @param X string - * @param Y string to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.10 - */ -#define ck_assert_str_le(X, Y) _ck_assert_str(X, <=, Y, 0, 0) - -/** - * Check two strings to determine if 00) - * - * If X or Y is NULL the test fails. - * If not 0, Y, 0, 0) - -/** - * Check two strings to determine if 0>=strcmp(X,Y) (e.g. strcmp(X,Y)<=0) - * - * If X or Y is NULL the test fails. - * If not 0>=strcmp(X,Y), the test fails. - * - * @param X string - * @param Y string to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.10 - */ -#define ck_assert_str_ge(X, Y) _ck_assert_str(X, >=, Y, 0, 0) - -/** - * Check two strings to determine if 0==strcmp(X,Y) or if both are undefined - * - * If both X and Y are NULL the test passes. However, if only one is NULL - * the test fails. - * If not ((X==NULL)&&(Y==NULL)) || (0==strcmp(X,Y)), the test fails. - * - * @param X string - * @param Y string to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_pstr_eq(X, Y) _ck_assert_str(X, ==, Y, 1, 0) - -/** - * Check two strings to determine if 0!=strcmp(X,Y) or one of them is undefined - * - * If either X or Y is NULL the test passes, however if both are NULL - * the test fails. - * If not (X!=NULL)&&(Y!=NULL)&&(0!=strcmp(X,Y)), the test fails. - * - * @param X string - * @param Y string to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_pstr_ne(X, Y) _ck_assert_str(X, !=, Y, 0, 1) - -/* Memory location comparison macros with improved output compared to ck_assert() */ -/* OP might be any operator that can be used in '0 OP memcmp(X,Y,L)' comparison */ -/* The x and y parameter swap in memcmp() is needed to handle >, >=, <, <= operators */ -/* Output is limited to CK_MAX_ASSERT_MEM_PRINT_SIZE bytes */ -#ifndef CK_MAX_ASSERT_MEM_PRINT_SIZE -#define CK_MAX_ASSERT_MEM_PRINT_SIZE 64 -#endif - -/* Memory location comparison macros with improved output compared to ck_assert() */ -/* OP might be any operator that can be used in '0 OP memcmp(X,Y,L)' comparison */ -/* The x and y parameter swap in memcmp() is needed to handle >, >=, <, <= operators */ -/* Output is limited to CK_MAX_ASSERT_MEM_PRINT_SIZE bytes */ -#ifndef CK_MAX_ASSERT_MEM_PRINT_SIZE -#define CK_MAX_ASSERT_MEM_PRINT_SIZE 64 -#endif - -#define _ck_assert_mem(X, OP, Y, L) do { \ - const uint8_t* _ck_x = (const uint8_t*)(X); \ - const uint8_t* _ck_y = (const uint8_t*)(Y); \ - size_t _ck_l = (L); \ - char _ck_x_str[CK_MAX_ASSERT_MEM_PRINT_SIZE * 2 + 1]; \ - char _ck_y_str[CK_MAX_ASSERT_MEM_PRINT_SIZE * 2 + 1]; \ - static const char _ck_hexdigits[] = "0123456789abcdef"; \ - size_t _ck_i; \ - size_t _ck_maxl = (_ck_l > CK_MAX_ASSERT_MEM_PRINT_SIZE) ? CK_MAX_ASSERT_MEM_PRINT_SIZE : _ck_l; \ - for (_ck_i = 0; _ck_i < _ck_maxl; _ck_i++) { \ - _ck_x_str[_ck_i * 2 ] = _ck_hexdigits[(_ck_x[_ck_i] >> 4) & 0xF]; \ - _ck_y_str[_ck_i * 2 ] = _ck_hexdigits[(_ck_y[_ck_i] >> 4) & 0xF]; \ - _ck_x_str[_ck_i * 2 + 1] = _ck_hexdigits[_ck_x[_ck_i] & 0xF]; \ - _ck_y_str[_ck_i * 2 + 1] = _ck_hexdigits[_ck_y[_ck_i] & 0xF]; \ - } \ - _ck_x_str[_ck_i * 2] = 0; \ - _ck_y_str[_ck_i * 2] = 0; \ - if (_ck_maxl != _ck_l) { \ - _ck_x_str[_ck_i * 2 - 2] = '.'; \ - _ck_y_str[_ck_i * 2 - 2] = '.'; \ - _ck_x_str[_ck_i * 2 - 1] = '.'; \ - _ck_y_str[_ck_i * 2 - 1] = '.'; \ - } \ - ck_assert_msg(0 OP memcmp(_ck_y, _ck_x, _ck_l), \ - "Assertion '%s' failed: %s == \"%s\", %s == \"%s\"", #X" "#OP" "#Y, #X, _ck_x_str, #Y, _ck_y_str); \ -} while (0) -/** - * Check two memory locations to determine if 0==memcmp(X,Y,L) - * - * If not 0==memcmp(X,Y,L), the test fails. - * - * @param X memory location - * @param Y memory location to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_mem_eq(X, Y, L) _ck_assert_mem(X, ==, Y, L) -/** - * Check two memory locations to determine if 0!=memcmp(X,Y,L) - * - * If not 0!=memcmp(X,Y,L), the test fails. - * - * @param X memory location - * @param Y memory location to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_mem_ne(X, Y, L) _ck_assert_mem(X, !=, Y, L) -/** - * Check two memory locations to determine if 00) - * - * If not 0=0) - * - * If not 0<=memcmp(X,Y,L), the test fails. - * - * @param X memory location - * @param Y memory location to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_mem_le(X, Y, L) _ck_assert_mem(X, <=, Y, L) -/** - * Check two memory locations to determine if 00) - * - * If not 0, Y, L) -/** - * Check two memory locations to determine if 0>=memcmp(X,Y,L) (e.g. memcmp(X,Y,L)<=0) - * - * If not 0>=memcmp(X,Y,L), the test fails. - * - * @param X memory location - * @param Y memory location to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_mem_ge(X, Y, L) _ck_assert_mem(X, >=, Y, L) - -/* Pointer comparison macros with improved output compared to ck_assert(). */ -/* OP may only be == or != */ -#define _ck_assert_ptr(X, OP, Y) do { \ - const void* _ck_x = (X); \ - const void* _ck_y = (Y); \ - ck_assert_msg(_ck_x OP _ck_y, "Assertion '%s' failed: %s == %#lx, %s == %#lx", #X" "#OP" "#Y, #X, (unsigned long)(uintptr_t)_ck_x, #Y, (unsigned long)(uintptr_t)_ck_y); \ -} while (0) - -/* Pointer against NULL comparison macros with improved output - * compared to ck_assert(). */ -/* OP may only be == or != */ -#define _ck_assert_ptr_null(X, OP) do { \ - const void* _ck_x = (X); \ - ck_assert_msg(_ck_x OP NULL, \ - "Assertion '%s' failed: %s == %#lx", \ - #X" "#OP" NULL", \ - #X, (unsigned long)(uintptr_t)_ck_x); \ -} while (0) - -/** - * Check if two pointers are equal. - * - * If the two passed pointers are not equal, the test - * fails. - * - * @param X pointer - * @param Y pointer to compare against X - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.9.10 - */ -#define ck_assert_ptr_eq(X, Y) _ck_assert_ptr(X, ==, Y) - -/** - * Check if two pointers are not. - * - * If the two passed pointers are equal, the test fails. - * - * @param X pointer - * @param Y pointer to compare against X - * - * @since 0.9.10 - */ -#define ck_assert_ptr_ne(X, Y) _ck_assert_ptr(X, !=, Y) - -/** - * Check if a pointer is equal to NULL. - * - * If X != NULL, the test fails. - * - * @param X pointer to compare against NULL - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ptr_null(X) _ck_assert_ptr_null(X, ==) - -/** - * Check if a pointer is not equal to NULL. - * - * If X == NULL, the test fails. - * - * @param X pointer to compare against NULL - * - * @note If the check fails, the remaining of the test is aborted - * - * @since 0.11.0 - */ -#define ck_assert_ptr_nonnull(X) _ck_assert_ptr_null(X, !=) - -/** - * Mark the last point reached in a unit test. - * - * If the test throws a signal or exits, the location noted with the - * failure is the last location of a ck_assert*() or ck_abort() call. - * Use mark_point() to record intermediate locations (useful for tracking down - * crashes or exits). - * - * @since 0.6.0 -*/ -#define mark_point() _mark_point(__FILE__,__LINE__) - -/* Non macro version of #mark_point */ -CK_DLL_EXP void CK_EXPORT _mark_point(const char *file, int line); - -/** - * Enum describing the possible results of a test - */ -enum test_result -{ - CK_TEST_RESULT_INVALID, /**< Default value; should not encounter this */ - CK_PASS, /**< Test passed */ - CK_FAILURE, /**< Test completed but failed */ - CK_ERROR /**< Test failed to complete - (unexpected signal or non-zero early exit) */ -}; - -/** - * Enum specifying the verbosity of output a SRunner should produce - */ -enum print_output -{ - CK_SILENT, /**< No output */ - CK_MINIMAL, /**< Only summary output */ - CK_NORMAL, /**< All failed tests */ - CK_VERBOSE, /**< All tests */ - CK_ENV, /**< Look at environment var CK_VERBOSITY - for what verbosity to use, which can be - either "silent", "minimal", "normal", - or "verbose". If the environment variable - is not set, then CK_NORMAL will be used.*/ -#if 0 - CK_SUBUNIT, /**< Run as a subunit child process */ -#endif - CK_LAST /**< Not a valid option */ -}; - -/** - * Holds state for a running of a test suite - */ -typedef struct SRunner SRunner; - -/** - * Opaque type for a test failure - */ -typedef struct TestResult TestResult; - -/** - * Enum representing the types of contexts for a test - */ -enum ck_result_ctx -{ - CK_CTX_INVALID, /**< Default value; should not encounter this */ - CK_CTX_SETUP, /**< Setup before a test */ - CK_CTX_TEST, /**< Body of test itself */ - CK_CTX_TEARDOWN /**< Teardown after a test */ -}; - -/** - * Retrieve type of result that the given test result represents. - * - * This is a member of test_result, and can represent a - * pass, failure, or error. - * - * @param tr test result to retrieve result from - * - * @return result of given test - * - * @since 0.6.0 - */ -CK_DLL_EXP int CK_EXPORT tr_rtype(TestResult * tr); - -/** - * Retrieve context in which the result occurred for the given test result. - * - * The types of contents include the test setup, teardown, or the - * body of the test itself. - * - * @param tr test result to retrieve context from - * - * @return context to which the given test result applies - * - * @since 0.8.0 - */ -CK_DLL_EXP enum ck_result_ctx CK_EXPORT tr_ctx(TestResult * tr); - -/** - * Retrieve failure message from test result, if applicable. - * - * @return pointer to a message, if one exists. NULL otherwise. - * - * @since 0.6.0 - */ -CK_DLL_EXP const char *CK_EXPORT tr_msg(TestResult * tr); - -/** - * Retrieve line number at which a failure occurred, if applicable. - * - * @return If the test resulted in a failure, returns the line number - * that the failure occurred on; otherwise returns -1. - * - * @since 0.6.0 - */ -CK_DLL_EXP int CK_EXPORT tr_lno(TestResult * tr); - -/** - * Retrieve file name at which a failure occurred, if applicable. - * - * @return If the test resulted in a failure, returns a string - * containing the name of the file where the failure - * occurred; otherwise returns NULL. - * - * @since 0.6.0 - */ -CK_DLL_EXP const char *CK_EXPORT tr_lfile(TestResult * tr); - -/** - * Retrieve test case name in which a failure occurred, if applicable. - * - * @return If the test resulted in a failure, returns a string - * containing the name of the test suite where the failure - * occurred; otherwise returns NULL. - * - * @since 0.6.0 - */ -CK_DLL_EXP const char *CK_EXPORT tr_tcname(TestResult * tr); - -/** - * Creates a suite runner for the given suite. - * - * Once created, additional suites can be added to the - * suite runner using srunner_add_suite(), and the suite runner can be - * run with srunner_run_all(). Once finished, the suite runner - * must be freed with srunner_free(). - * - * @param s suite to generate a suite runner for - * - * @return suite runner for the given suite - * - * @since 0.6.0 - */ -CK_DLL_EXP SRunner *CK_EXPORT srunner_create(Suite * s); - -/** - * Add an additional suite to a suite runner. - * - * The first suite in a suite runner is always added in srunner_create(). - * This call adds additional suites to a suite runner. - * - * @param sr suite runner to add the given suite - * @param s suite to add to the given suite runner - * - * @since 0.7.0 - */ -CK_DLL_EXP void CK_EXPORT srunner_add_suite(SRunner * sr, Suite * s); - -/** - * Frees a suite runner, including all contained suite and test cases. - * - * This call is responsible for freeing all resources related to a - * suite runner and all contained suites and test cases. Suite and - * test cases need not be freed individually, as this call handles that. - * - * @param sr suite runner to free - * - * @since 0.6.0 - */ -CK_DLL_EXP void CK_EXPORT srunner_free(SRunner * sr); - -/** - * Runs a suite runner and all contained suite, printing results to - * stdout as specified by the print_mode. - * - * In addition to running all suites, if the suite runner has been - * configured to output to a log, that is also performed. - * - * Note that if the CK_RUN_CASE, CK_RUN_SUITE, CK_INCLUDE_TAGS and/or - * CK_EXCLUDE_TAGS environment variables are defined, then only the - * named suites or test cases will run. - * - * @param sr suite runner to run all suites from - * @param print_mode the verbosity in which to report results to stdout - * - * @since 0.6.0 - */ -CK_DLL_EXP void CK_EXPORT srunner_run_all(SRunner * sr, - enum print_output print_mode); - -/** - * Run a specific suite or test case from a suite runner, printing results - * to stdout as specified by the print_mode. - * - * In addition to running any applicable suites or test cases, if the - * suite runner has been configured to output to a log, that is also - * performed. - * - * Note that if the sname and tcname parameters are passed as null - * then the function will fallback to using the environment variables - * CK_RUN_SUITE and CK_RUN_CASE respectively in order to select the - * suite/cases. - * - * Similarly if the CK_INCLUDE_TAGS and/or CK_EXCLUDE_TAGS environment - * variables are defined then these will further filter the test cases - * (see srunner_run_tagged, below). - * - * @param sr suite runner where the given suite or test case must be - * @param sname suite name to run. A NULL means use the value of the - * environment variable CK_RUN_SUITE if set, otherwise run "any/every - * suite". - * @param tcname test case name to run. A NULL means use the value of - * the environment variable CK_RUN_CASE if set, otherwise run - * "any/every case". - * @param print_mode the verbosity in which to report results to stdout - * - * @since 0.9.9 - */ -CK_DLL_EXP void CK_EXPORT srunner_run(SRunner * sr, const char *sname, - const char *tcname, - enum print_output print_mode); - - -/** - * Run a specific suite or test case or testcases with specific tags - * from a suite runner, printing results to stdout as specified by the - * print_mode. - * - * In addition to running any applicable suites or test cases, if the - * suite runner has been configured to output to a log, that is also - * performed. - * - * Note that if sname, tcname, include_tags, exclude_tags parameters - * are passed as NULL then if the environment variables CK_RUN_SUITE, - * CK_RUN_CASE, CK_INCLUDE_TAGS, CK_EXCLUDE_TAGS are defined then these - * values will be used instead. - * - * @param sr suite runner where the given suite or test case must be - * @param sname suite name to run. A NULL means use the value of the - * environment variable CK_RUN_SUITE if set, otherwise run "any/every - * suite". - * @param tcname test case name to run. A NULL means use the value of - * the environment variable CK_RUN_CASE if set, otherwise run - * "any/every case". - * @param include_tags space separate list of tags. Only run test - * cases that share one of these tags. A NULL means use the value of - * the environment variable CK_INCLUDE_TAGS if set, otherwise run - * "any/every test case". - * @param exclude_tags space separate list of tags. Only run test - * cases that do not share one of these tags even if they are selected - * by an included tag. A NULL means use the value of the environment - * variable CK_EXCLUDE_TAGS if set, otherwise run "any/every test - * case". - * @param print_mode the verbosity in which to report results to stdout - * - * @since 0.11.0 - */ -CK_DLL_EXP void CK_EXPORT srunner_run_tagged(SRunner * sr, const char *sname, - const char *tcname, - const char *include_tags, - const char *exclude_tags, - enum print_output print_mode); - -/** - * Retrieve the number of failed tests executed by a suite runner. - * - * This value represents both test failures and errors. - * - * @param sr suite runner to query for all failed tests - * - * @return number of test failures and errors found by the suite runner - * - * @since 0.6.1 - */ -CK_DLL_EXP int CK_EXPORT srunner_ntests_failed(SRunner * sr); - -/** - * Retrieve the total number of tests run by a suite runner. - * - * @param sr suite runner to query for all tests run - * - * @return number of all tests run by the suite runner - * - * @since 0.6.1 - */ -CK_DLL_EXP int CK_EXPORT srunner_ntests_run(SRunner * sr); - -/** - * Return an array of results for all failures found by a suite runner. - * - * Number of results is equal to srunner_nfailed_tests(). - * - * Information about individual results can be queried using: - * tr_rtype(), tr_ctx(), tr_msg(), tr_lno(), tr_lfile(), and tr_tcname(). - * - * Memory is malloc'ed and must be freed; however free the entire structure - * instead of individual test cases. - * - * @param sr suite runner to retrieve results from - * - * @return array of TestResult objects - * - * @since 0.6.0 - */ -CK_DLL_EXP TestResult **CK_EXPORT srunner_failures(SRunner * sr); - -/** - * Return an array of results for all tests run by a suite runner. - * - * Number of results is equal to srunner_ntests_run(), and excludes - * failures due to setup function failure. - * - * Information about individual results can be queried using: - * tr_rtype(), tr_ctx(), tr_msg(), tr_lno(), tr_lfile(), and tr_tcname(). - * - * Memory is malloc'ed and must be freed; however free the entire structure - * instead of individual test cases. - * - * @param sr suite runner to retrieve results from - * - * @return array of TestResult objects - * - * @since 0.6.1 -*/ -CK_DLL_EXP TestResult **CK_EXPORT srunner_results(SRunner * sr); - -/** - * Print the results contained in an SRunner to stdout. - * - * @param sr suite runner to print results for to stdout - * @param print_mode the print_output (verbosity) to use to report - * the result - * - * @since 0.7.0 - */ -CK_DLL_EXP void CK_EXPORT srunner_print(SRunner * sr, - enum print_output print_mode); - -/** - * Set the suite runner to output the result in log format to the - * given file. - * - * Note: log file setting is an initialize only operation -- it should - * be done immediately after SRunner creation, and the log file can't be - * changed after being set. - * - * This setting does not conflict with the other log output types; - * all logging types can occur concurrently if configured. - * - * @param sr suite runner to log results of in log format - * @param fname file name to output log results to - * - * @since 0.7.1 -*/ -CK_DLL_EXP void CK_EXPORT srunner_set_log(SRunner * sr, const char *fname); - -/** - * Checks if the suite runner is assigned a file for log output. - * - * @param sr suite runner to check - * - * @return 1 iff the suite runner currently is configured to output - * in log format; 0 otherwise - * - * @since 0.7.1 - */ -CK_DLL_EXP int CK_EXPORT srunner_has_log(SRunner * sr); - -/** - * Retrieves the name of the currently assigned file - * for log output, if any exists. - * - * @return the name of the log file, or NULL if none is configured - * - * @since 0.7.1 - */ -CK_DLL_EXP const char *CK_EXPORT srunner_log_fname(SRunner * sr); - -/** - * Set the suite runner to output the result in XML format to the - * given file. - * - * Note: XML file setting is an initialize only operation -- it should - * be done immediately after SRunner creation, and the XML file can't be - * changed after being set. - * - * This setting does not conflict with the other log output types; - * all logging types can occur concurrently if configured. - * - * @param sr suite runner to log results of in XML format - * @param fname file name to output XML results to - * - * @since 0.9.1 -*/ -CK_DLL_EXP void CK_EXPORT srunner_set_xml(SRunner * sr, const char *fname); - -/** - * Checks if the suite runner is assigned a file for XML output. - * - * @param sr suite runner to check - * - * @return 1 iff the suite runner currently is configured to output - * in XML format; 0 otherwise - * - * @since 0.9.1 - */ -CK_DLL_EXP int CK_EXPORT srunner_has_xml(SRunner * sr); - -/** - * Retrieves the name of the currently assigned file - * for XML output, if any exists. - * - * @return the name of the XML file, or NULL if none is configured - * - * @since 0.9.1 - */ -CK_DLL_EXP const char *CK_EXPORT srunner_xml_fname(SRunner * sr); - -/** - * Set the suite runner to output the result in TAP format to the - * given file. - * - * Note: TAP file setting is an initialize only operation -- it should - * be done immediately after SRunner creation, and the TAP file can't be - * changed after being set. - * - * This setting does not conflict with the other log output types; - * all logging types can occur concurrently if configured. - * - * @param sr suite runner to log results of in TAP format - * @param fname file name to output TAP results to - * - * @since 0.9.12 -*/ -CK_DLL_EXP void CK_EXPORT srunner_set_tap(SRunner * sr, const char *fname); - -/** - * Checks if the suite runner is assigned a file for TAP output. - * - * @param sr suite runner to check - * - * @return 1 iff the suite runner currently is configured to output - * in TAP format; 0 otherwise - * - * @since 0.9.12 - */ -CK_DLL_EXP int CK_EXPORT srunner_has_tap(SRunner * sr); - -/** - * Retrieves the name of the currently assigned file - * for TAP output, if any exists. - * - * @return the name of the TAP file, or NULL if none is configured - * - * @since 0.9.12 - */ -CK_DLL_EXP const char *CK_EXPORT srunner_tap_fname(SRunner * sr); - -/** - * Enum describing the current fork usage. - */ -enum fork_status -{ - CK_FORK_GETENV, /**< look in the environment for CK_FORK */ - CK_FORK, /**< call fork to run tests */ - CK_NOFORK /**< don't call fork */ -}; - -/** - * Retrieve the current fork status for the given suite runner - * - * @param sr suite runner to check fork status of - * - * @since 0.8.0 - */ -CK_DLL_EXP enum fork_status CK_EXPORT srunner_fork_status(SRunner * sr); - -/** - * Set the fork status for a given suite runner. - * - * The default fork status is CK_FORK_GETENV, which will look - * for the CK_FORK environment variable, which can be set to - * "yes" or "no". If the environment variable is not present, - * CK_FORK will be used if fork() is available on the system, - * otherwise CK_NOFORK is used. - * - * If set to CK_FORK or CK_NOFORK, the environment variable - * if defined is ignored. - * - * If Check is compiled without support for fork(), attempting - * to set the status to CK_FORK is ignored. - * - * @param sr suite runner to assign the fork status to - * @param fstat fork status to assign - * - * @since 0.8.0 - */ -CK_DLL_EXP void CK_EXPORT srunner_set_fork_status(SRunner * sr, - enum fork_status fstat); - -/** - * Invoke fork() during a test and assign the child to the same - * process group that the rest of the test case uses. - * - * One can invoke fork() directly during a test; however doing so - * may not guarantee that any children processes are destroyed once - * the test finishes. Once a test has completed, all processes in - * the process group will be killed; using this wrapper will prevent - * orphan processes. - * - * If Check is compiled without fork() support this call simply - * return -1 and does nothing. - * - * @return On success, the PID of the child process is returned in - * the parent, and 0 is returned in the child. On failure, - * a value of -1 is returned to the parent process and no - * child process is created. - * - * @since 0.9.3 - */ -CK_DLL_EXP pid_t CK_EXPORT check_fork(void); - -/** - * Wait for the pid and exit. - * - * This is to be used in conjunction with check_fork(). When called, - * will wait for the given process to terminate. If the process - * exited without error, exit(EXIT_SUCCESS) is invoked; otherwise - * exit(EXIT_FAILURE) is invoked. - * - * If Check is compiled without support for fork(), this invokes - * exit(EXIT_FAILURE). - * - * @param pid process to wait for, created by check_fork() - * - * @since 0.9.3 - */ -CK_DLL_EXP void CK_EXPORT check_waitpid_and_exit(pid_t pid) CK_ATTRIBUTE_NORETURN; - -/** - * Set the maximal assertion message size. - * - * This protects the code against unintentional extremely large assertion messages - * (values of up to 4GB were seen in the wild). - * The usual size for a message is less than 80 bytes. - * - * If the environment variable CK_MAX_MSG_SIZE is defined to a positive value, it is used. - * Otherwise, if a positive maximal message size is set via this function, it is used. - * Otherwise, the maximal message size is one assigned at compile time (4K bytes). - * - * @param max_msg_size the maximal assertion message size. - * - * @since 0.12.0 - */ -CK_DLL_EXP void CK_EXPORT check_set_max_msg_size(size_t max_msg_size); - -#ifdef __cplusplus -CK_CPPEND -#endif - -#endif /* CHECK_H */ -- Gitee From c134ef61d5889d6251850daf9383d95315d7eb7b Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 22:12:33 +0800 Subject: [PATCH 23/34] =?UTF-8?q?=E7=94=9F=E6=88=90=E9=9D=99=E6=80=81?= =?UTF-8?q?=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/CMakeLists.txt | 1 + yonglin_zhang/link_list/src/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/yonglin_zhang/link_list/CMakeLists.txt b/yonglin_zhang/link_list/CMakeLists.txt index 0809288..c6fc474 100644 --- a/yonglin_zhang/link_list/CMakeLists.txt +++ b/yonglin_zhang/link_list/CMakeLists.txt @@ -1,4 +1,5 @@ set(LINK_SDK_NAME "link_list") +set(LINK_SDK_NAME_STATIC "link_list-static") add_subdirectory(src) add_subdirectory(test) \ No newline at end of file diff --git a/yonglin_zhang/link_list/src/CMakeLists.txt b/yonglin_zhang/link_list/src/CMakeLists.txt index 1fc434a..ab5fb40 100644 --- a/yonglin_zhang/link_list/src/CMakeLists.txt +++ b/yonglin_zhang/link_list/src/CMakeLists.txt @@ -10,4 +10,4 @@ set(INCLUDE_DIR include_directories(${INCLUDE_DIR}) add_library(${LINK_SDK_NAME} SHARED ${LIB_SRC}) -add_library(${LINK_SDK_NAME} STATIC ${LIB_SRC}) +add_library(${LINK_SDK_NAME_STATIC} STATIC ${LIB_SRC}) -- Gitee From 2f7d9f59c80c24d2e0302da23174bdd18c320aa7 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 22:13:11 +0800 Subject: [PATCH 24/34] =?UTF-8?q?=E4=BF=AE=E6=94=B9cmake?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/test/CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/yonglin_zhang/link_list/test/CMakeLists.txt b/yonglin_zhang/link_list/test/CMakeLists.txt index e4f4ee1..1de33fe 100644 --- a/yonglin_zhang/link_list/test/CMakeLists.txt +++ b/yonglin_zhang/link_list/test/CMakeLists.txt @@ -2,12 +2,15 @@ set(INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/. ${CMAKE_CURRENT_SOURCE_DIR}/../include ${CMAKE_CURRENT_SOURCE_DIR}/../../include + ${CMAKE_SOURCE_DIR}/build/unit-testing/ + ${CMAKE_SOURCE_DIR}/build/unit-testing/src/ ) set(DEP_LIBS check link_list check_interface + pthread ) set(DEP_LIBS_DIR @@ -29,7 +32,7 @@ link_directories(${DEP_LIBS_DIR}) include_directories(${INCLUDE_DIRS}) add_library(${TEST_LIB_NAME} SHARED ${SRC}) -add_library(${TEST_LIB_NAME} STATIC ${SRC}) +target_link_libraries(${TEST_LIB_NAME} link_list) -add_executable(check_interface check_interface.c) -target_link_libraries(check_interface ${DEP_LIBS}) \ No newline at end of file +add_executable(interface_test check_interface.c) +target_link_libraries(interface_test ${DEP_LIBS} check_interface) \ No newline at end of file -- Gitee From 33118147a98a085868dba520f19395ba180b5208 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 12 Feb 2022 22:13:43 +0800 Subject: [PATCH 25/34] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/test/check_interface.c | 8 ++++++-- yonglin_zhang/link_list/test/check_interface.h | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/yonglin_zhang/link_list/test/check_interface.c b/yonglin_zhang/link_list/test/check_interface.c index ea6a007..2ca6ae9 100644 --- a/yonglin_zhang/link_list/test/check_interface.c +++ b/yonglin_zhang/link_list/test/check_interface.c @@ -4,12 +4,16 @@ int main() { SRunner *sr; + int number_failed = 0; sr = srunner_create(check_init()); + /* can debug with gdb */ srunner_set_fork_status(sr, CK_NOFORK); - srunner_run_all(sr, CK_VERBOSE); - + srunner_run_all (sr, CK_VERBOSE); + number_failed = srunner_ntests_failed(sr); srunner_free(sr); + + return 0; } \ No newline at end of file diff --git a/yonglin_zhang/link_list/test/check_interface.h b/yonglin_zhang/link_list/test/check_interface.h index 82b9fe7..724bf7c 100644 --- a/yonglin_zhang/link_list/test/check_interface.h +++ b/yonglin_zhang/link_list/test/check_interface.h @@ -5,4 +5,4 @@ Suite *check_init(void); -#endif; \ No newline at end of file +#endif \ No newline at end of file -- Gitee From db927383a4bd40621e5148b4cf7d7d1ec7058f5b Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sun, 13 Feb 2022 21:16:00 +0800 Subject: [PATCH 26/34] =?UTF-8?q?=E5=A8=98=E7=9A=84=E7=BB=88=E4=BA=8E?= =?UTF-8?q?=E6=89=BE=E5=88=B0=E4=BA=86=E8=AE=A9=E4=BA=BA=E7=94=9F=E6=B0=94?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/test/check_init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yonglin_zhang/link_list/test/check_init.c b/yonglin_zhang/link_list/test/check_init.c index ad7b330..5e96d57 100644 --- a/yonglin_zhang/link_list/test/check_init.c +++ b/yonglin_zhang/link_list/test/check_init.c @@ -22,4 +22,6 @@ Suite *check_init(void) tcase_add_test(tc_core, test_init); suite_add_tcase(s, tc_core); + + return s; } \ No newline at end of file -- Gitee From e82a5ff292bc4c469b726fc35347e2c3427cb883 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sun, 13 Feb 2022 21:23:51 +0800 Subject: [PATCH 27/34] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=88=9D=E5=A7=8B=E5=8C=96=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/src/link_list.c | 3 +++ yonglin_zhang/link_list/test/check_init.c | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c index 14010ad..eea3bb7 100644 --- a/yonglin_zhang/link_list/src/link_list.c +++ b/yonglin_zhang/link_list/src/link_list.c @@ -13,6 +13,9 @@ typedef struct _link_list node; /* 初始化句柄 */ int list_init(link_list **ctx) { + if(ctx == NULL) { + return ALG_BAD_INPUT; + } if(*ctx != NULL) { return ALG_BAD_INPUT; } diff --git a/yonglin_zhang/link_list/test/check_init.c b/yonglin_zhang/link_list/test/check_init.c index 5e96d57..eeddd8c 100644 --- a/yonglin_zhang/link_list/test/check_init.c +++ b/yonglin_zhang/link_list/test/check_init.c @@ -11,6 +11,13 @@ START_TEST(test_init) } END_TEST +START_TEST(test_input) +{ + link_list *ctx = NULL; + ck_assert_int_eq(list_init(NULL), ALG_BAD_INPUT); +} +END_TEST + Suite *check_init(void) { Suite *s; @@ -20,6 +27,7 @@ Suite *check_init(void) tc_core = tcase_create("core"); tcase_add_test(tc_core, test_init); + tcase_add_test(tc_core, test_input); suite_add_tcase(s, tc_core); -- Gitee From f873c6fd9bfb73902b8fd2a1d0499a1445810bd9 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sun, 13 Feb 2022 21:34:34 +0800 Subject: [PATCH 28/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/src/link_list.c | 2 + yonglin_zhang/link_list/test/CMakeLists.txt | 1 + yonglin_zhang/link_list/test/check_add.c | 41 +++++++++++++++++++ .../link_list/test/check_interface.c | 1 + .../link_list/test/check_interface.h | 1 + 5 files changed, 46 insertions(+) create mode 100644 yonglin_zhang/link_list/test/check_add.c diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c index eea3bb7..1f2ca96 100644 --- a/yonglin_zhang/link_list/src/link_list.c +++ b/yonglin_zhang/link_list/src/link_list.c @@ -46,6 +46,8 @@ int list_add_head(link_list *ctx, data_type data) t->next = ctx->next; ctx->next = t; + + return ALG_OK; } /* 尾部插入一个节点 */ diff --git a/yonglin_zhang/link_list/test/CMakeLists.txt b/yonglin_zhang/link_list/test/CMakeLists.txt index 1de33fe..c0b8451 100644 --- a/yonglin_zhang/link_list/test/CMakeLists.txt +++ b/yonglin_zhang/link_list/test/CMakeLists.txt @@ -20,6 +20,7 @@ set(DEP_LIBS_DIR ) set(SRC + check_add.c check_init.c check_interface.c ) diff --git a/yonglin_zhang/link_list/test/check_add.c b/yonglin_zhang/link_list/test/check_add.c new file mode 100644 index 0000000..7edddea --- /dev/null +++ b/yonglin_zhang/link_list/test/check_add.c @@ -0,0 +1,41 @@ +#include + +#include "check_interface.h" +#include "link_list.h" +#include "alg_errno.h" + +START_TEST(test_ok) +{ + link_list *ctx = NULL; + + ck_assert_int_eq(list_init(&ctx), ALG_OK); + + ck_assert_int_eq(list_add_head(ctx, 10), ALG_OK); + ck_assert_int_eq(list_add_rear(ctx, 10), ALG_OK); +} +END_TEST + +START_TEST(test_not_init) +{ + link_list *ctx = NULL; + + ck_assert_int_eq(list_add_head(ctx, 10), ALG_BAD_INPUT); + ck_assert_int_eq(list_add_rear(ctx, 10), ALG_BAD_INPUT); +} +END_TEST + +Suite *check_add(void) +{ + Suite *s; + TCase *tc_core; + + s = suite_create("list_add test"); + + tc_core = tcase_create("core"); + tcase_add_test(tc_core, test_ok); + tcase_add_test(tc_core, test_not_init); + + suite_add_tcase(s, tc_core); + + return s; +} \ No newline at end of file diff --git a/yonglin_zhang/link_list/test/check_interface.c b/yonglin_zhang/link_list/test/check_interface.c index 2ca6ae9..584ab87 100644 --- a/yonglin_zhang/link_list/test/check_interface.c +++ b/yonglin_zhang/link_list/test/check_interface.c @@ -7,6 +7,7 @@ int main() int number_failed = 0; sr = srunner_create(check_init()); + srunner_add_suite(sr, check_add()); /* can debug with gdb */ srunner_set_fork_status(sr, CK_NOFORK); diff --git a/yonglin_zhang/link_list/test/check_interface.h b/yonglin_zhang/link_list/test/check_interface.h index 724bf7c..c454259 100644 --- a/yonglin_zhang/link_list/test/check_interface.h +++ b/yonglin_zhang/link_list/test/check_interface.h @@ -4,5 +4,6 @@ #include "check.h" Suite *check_init(void); +Suite *check_add(void); #endif \ No newline at end of file -- Gitee From 7b68284f7a71585a4a19c5f06daf49bd17a26837 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 19 Feb 2022 20:23:45 +0800 Subject: [PATCH 29/34] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=A3=B0=E6=98=8E?= =?UTF-8?q?=E9=94=99=E8=AF=AF=EF=BC=8C=E9=87=8D=E6=96=B0=E5=A3=B0=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/include/link_list.h | 2 +- yonglin_zhang/link_list/src/link_list.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/yonglin_zhang/link_list/include/link_list.h b/yonglin_zhang/link_list/include/link_list.h index a189be9..b6aef2f 100644 --- a/yonglin_zhang/link_list/include/link_list.h +++ b/yonglin_zhang/link_list/include/link_list.h @@ -54,7 +54,7 @@ int list_add_rear(link_list *ctx, data_type data); * * \return \c ALG_OK 删除成功 */ -int lint_delete_first_target(link_list *ctx, data_type target); +int list_delete_first_target(link_list *ctx, data_type target); /** * \brief 清空链表中的元素 diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c index 1f2ca96..cf0edb5 100644 --- a/yonglin_zhang/link_list/src/link_list.c +++ b/yonglin_zhang/link_list/src/link_list.c @@ -77,7 +77,7 @@ int list_add_rear(link_list *ctx, data_type data) } /* 删除第一个为target元素的节点 */ -int lint_delete_first_target(link_list *ctx, data_type target) +int list_delete_first_target(link_list *ctx, data_type target) { node *t = NULL; -- Gitee From d551793c90842be88651b972f89c3882e92d6b9f Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 19 Feb 2022 20:50:03 +0800 Subject: [PATCH 30/34] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E7=9A=84=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/test/check_interface.c | 1 + yonglin_zhang/link_list/test/check_interface.h | 1 + 2 files changed, 2 insertions(+) diff --git a/yonglin_zhang/link_list/test/check_interface.c b/yonglin_zhang/link_list/test/check_interface.c index 584ab87..696f2a7 100644 --- a/yonglin_zhang/link_list/test/check_interface.c +++ b/yonglin_zhang/link_list/test/check_interface.c @@ -8,6 +8,7 @@ int main() sr = srunner_create(check_init()); srunner_add_suite(sr, check_add()); + srunner_add_suite(sr, check_delete()); /* can debug with gdb */ srunner_set_fork_status(sr, CK_NOFORK); diff --git a/yonglin_zhang/link_list/test/check_interface.h b/yonglin_zhang/link_list/test/check_interface.h index c454259..7cb7474 100644 --- a/yonglin_zhang/link_list/test/check_interface.h +++ b/yonglin_zhang/link_list/test/check_interface.h @@ -5,5 +5,6 @@ Suite *check_init(void); Suite *check_add(void); +Suite *check_delete(void); #endif \ No newline at end of file -- Gitee From a84118b4d0a0daaf77e184419239d9d32c397596 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 19 Feb 2022 20:50:22 +0800 Subject: [PATCH 31/34] =?UTF-8?q?=E5=A3=B0=E6=98=8E=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=B9=B6=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../link_list/test/check_delete_first.c | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 yonglin_zhang/link_list/test/check_delete_first.c diff --git a/yonglin_zhang/link_list/test/check_delete_first.c b/yonglin_zhang/link_list/test/check_delete_first.c new file mode 100644 index 0000000..47d83b6 --- /dev/null +++ b/yonglin_zhang/link_list/test/check_delete_first.c @@ -0,0 +1,54 @@ +#include + +#include "check_interface.h" +#include "link_list.h" +#include "alg_errno.h" + +START_TEST(test_init) +{ + link_list *ctx = NULL; + ck_assert_int_eq(list_init(&ctx), ALG_OK); + ck_assert_int_eq(list_add_head(ctx, 10), ALG_OK); + ck_assert_int_eq(list_delete_first_target(ctx, 10), ALG_OK); +} +END_TEST + +START_TEST(test_input) +{ + link_list *ctx = NULL; + + //测试未初始化的指针和空指针 + ck_assert_int_eq(list_delete_first_target(ctx, 10), ALG_BAD_INPUT); + ck_assert_int_eq(list_delete_first_target(NULL, 10), ALG_BAD_INPUT); + + //测试初始化指针,但未添加任何元素 + ck_assert_int_eq(list_init(&ctx), ALG_OK); + ck_assert_int_eq(list_delete_first_target(ctx, 10), ALG_BAD_INPUT); +} +END_TEST + +START_TEST(test_not_exist) +{ + link_list *ctx = NULL; + ck_assert_int_eq(list_init(ctx), ALG_OK); + ck_assert_int_eq(list_add_head(ctx, 10), ALG_OK); + ck_assert_int_eq(list_delete_first_target(ctx, 32), ALG_NODE_NOT_EXIST); +} +END_TEST + +Suite *check_delete(void) +{ + Suite *s; + TCase *tc_core; + + s = suite_create("list_delete test"); + + tc_core = tcase_create("core"); + tcase_add_test(tc_core, test_init); + tcase_add_test(tc_core, test_input); + tcase_add_test(tc_core, test_not_exist); + + suite_add_tcase(s, tc_core); + + return s; +} \ No newline at end of file -- Gitee From c0c91ab70ec6429394c08f623910c36096030377 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 19 Feb 2022 21:41:10 +0800 Subject: [PATCH 32/34] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/test/CMakeLists.txt | 1 + yonglin_zhang/link_list/test/check_delete_first.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/yonglin_zhang/link_list/test/CMakeLists.txt b/yonglin_zhang/link_list/test/CMakeLists.txt index c0b8451..ad4a322 100644 --- a/yonglin_zhang/link_list/test/CMakeLists.txt +++ b/yonglin_zhang/link_list/test/CMakeLists.txt @@ -22,6 +22,7 @@ set(DEP_LIBS_DIR set(SRC check_add.c check_init.c + check_delete_first.c check_interface.c ) diff --git a/yonglin_zhang/link_list/test/check_delete_first.c b/yonglin_zhang/link_list/test/check_delete_first.c index 47d83b6..53766b3 100644 --- a/yonglin_zhang/link_list/test/check_delete_first.c +++ b/yonglin_zhang/link_list/test/check_delete_first.c @@ -30,7 +30,7 @@ END_TEST START_TEST(test_not_exist) { link_list *ctx = NULL; - ck_assert_int_eq(list_init(ctx), ALG_OK); + ck_assert_int_eq(list_init(&ctx), ALG_OK); ck_assert_int_eq(list_add_head(ctx, 10), ALG_OK); ck_assert_int_eq(list_delete_first_target(ctx, 32), ALG_NODE_NOT_EXIST); } -- Gitee From d0a37b971256ab580bef82a3bfd2a91ba428ac96 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 19 Feb 2022 22:07:39 +0800 Subject: [PATCH 33/34] =?UTF-8?q?=E6=B7=BB=E5=8A=A0clean=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E7=9A=84=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/src/link_list.c | 2 + yonglin_zhang/link_list/test/CMakeLists.txt | 1 + yonglin_zhang/link_list/test/check_free.c | 41 +++++++++++++++++++ .../link_list/test/check_interface.c | 1 + .../link_list/test/check_interface.h | 1 + 5 files changed, 46 insertions(+) create mode 100644 yonglin_zhang/link_list/test/check_free.c diff --git a/yonglin_zhang/link_list/src/link_list.c b/yonglin_zhang/link_list/src/link_list.c index cf0edb5..be42308 100644 --- a/yonglin_zhang/link_list/src/link_list.c +++ b/yonglin_zhang/link_list/src/link_list.c @@ -123,6 +123,8 @@ int list_clean(link_list *ctx) free(temp); } + ctx->next = NULL; + return ALG_OK; } diff --git a/yonglin_zhang/link_list/test/CMakeLists.txt b/yonglin_zhang/link_list/test/CMakeLists.txt index ad4a322..e356d66 100644 --- a/yonglin_zhang/link_list/test/CMakeLists.txt +++ b/yonglin_zhang/link_list/test/CMakeLists.txt @@ -22,6 +22,7 @@ set(DEP_LIBS_DIR set(SRC check_add.c check_init.c + check_free.c check_delete_first.c check_interface.c ) diff --git a/yonglin_zhang/link_list/test/check_free.c b/yonglin_zhang/link_list/test/check_free.c new file mode 100644 index 0000000..681f744 --- /dev/null +++ b/yonglin_zhang/link_list/test/check_free.c @@ -0,0 +1,41 @@ +#include + +#include "check_interface.h" +#include "link_list.h" +#include "alg_errno.h" + +START_TEST(test_init) +{ + link_list *ctx = NULL; + ck_assert_int_eq(list_init(&ctx), ALG_OK); + ck_assert_int_eq(list_add_head(ctx, 10), ALG_OK); + ck_assert_int_eq(list_clean(ctx), ALG_OK); + ck_assert_int_eq(list_clean(ctx), ALG_OK); +} +END_TEST + +START_TEST(test_input) +{ + link_list *ctx = NULL; + + ck_assert_int_eq(list_init(&ctx), ALG_OK); + ck_assert_int_eq(list_clean(NULL), ALG_BAD_INPUT); + ck_assert_int_eq(list_clean(ctx), ALG_OK); +} +END_TEST + +Suite *check_free(void) +{ + Suite *s; + TCase *tc_core; + + s = suite_create("list_clean test"); + + tc_core = tcase_create("core"); + tcase_add_test(tc_core, test_init); + tcase_add_test(tc_core, test_input); + + suite_add_tcase(s, tc_core); + + return s; +} \ No newline at end of file diff --git a/yonglin_zhang/link_list/test/check_interface.c b/yonglin_zhang/link_list/test/check_interface.c index 696f2a7..069aae4 100644 --- a/yonglin_zhang/link_list/test/check_interface.c +++ b/yonglin_zhang/link_list/test/check_interface.c @@ -9,6 +9,7 @@ int main() sr = srunner_create(check_init()); srunner_add_suite(sr, check_add()); srunner_add_suite(sr, check_delete()); + srunner_add_suite(sr, check_free()); /* can debug with gdb */ srunner_set_fork_status(sr, CK_NOFORK); diff --git a/yonglin_zhang/link_list/test/check_interface.h b/yonglin_zhang/link_list/test/check_interface.h index 7cb7474..a1621c7 100644 --- a/yonglin_zhang/link_list/test/check_interface.h +++ b/yonglin_zhang/link_list/test/check_interface.h @@ -6,5 +6,6 @@ Suite *check_init(void); Suite *check_add(void); Suite *check_delete(void); +Suite *check_free(void); #endif \ No newline at end of file -- Gitee From 417d74fd7f60565e6fb4177f75c9c5438661ee06 Mon Sep 17 00:00:00 2001 From: yonglin_zhang <1248825327@qq.com> Date: Sat, 19 Feb 2022 22:07:59 +0800 Subject: [PATCH 34/34] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yonglin_zhang/link_list/test/CMakeLists.txt | 2 +- yonglin_zhang/link_list/test/{check_free.c => check_clean.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename yonglin_zhang/link_list/test/{check_free.c => check_clean.c} (100%) diff --git a/yonglin_zhang/link_list/test/CMakeLists.txt b/yonglin_zhang/link_list/test/CMakeLists.txt index e356d66..1d4c16b 100644 --- a/yonglin_zhang/link_list/test/CMakeLists.txt +++ b/yonglin_zhang/link_list/test/CMakeLists.txt @@ -22,7 +22,7 @@ set(DEP_LIBS_DIR set(SRC check_add.c check_init.c - check_free.c + check_clean.c check_delete_first.c check_interface.c ) diff --git a/yonglin_zhang/link_list/test/check_free.c b/yonglin_zhang/link_list/test/check_clean.c similarity index 100% rename from yonglin_zhang/link_list/test/check_free.c rename to yonglin_zhang/link_list/test/check_clean.c -- Gitee