## Coverage Report

#### Created: 2026-05-04 15:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /home/liu/actions-runner/_work/ccv/ccv/test/case.h

    Line
    Count
    Source
    1
    #ifndef _GUARD_case_h_
    2
    #define _GUARD_case_h_
    3
    4
    #include <stdio.h>
    5
    #include <stdint.h>
    6
    #include <unistd.h>
    7
    8
    #ifndef CASE_UNIQUE_NAME_PREFIX
    9
    #define CASE_UNIQUE_NAME_PREFIX
    10
    #endif
    11
    12
    #ifndef CASE_TEST_DIR
    13
    #define CASE_TEST_DIR "."
    14
    #endif
    15
    16
    #define CASE_TESTS
    17
    18
    /* the following 9 lines to generate unique name was taken from Catch: https://github.com/philsquared/Catch
    19
     * here is the licence:
    20
     * Boost Software License - Version 1.0 - August 17th, 2003
    21
     *
    22
     * Permission is hereby granted, free of charge, to any person or organization
    23
     * obtaining a copy of the software and accompanying documentation covered by
    24
     * this license (the "Software") to use, reproduce, display, distribute,
    25
     * execute, and transmit the Software, and to prepare derivative works of the
    26
     * Software, and to permit third-parties to whom the Software is furnished to
    27
     * do so, all subject to the following:
    28
     *
    29
     * The copyright notices in the Software and this entire statement, including
    30
     * the above license grant, this restriction and the following disclaimer,
    31
     * must be included in all copies of the Software, in whole or in part, and
    32
     * all derivative works of the Software, unless such copies or derivative
    33
     * works are solely in the form of machine-executable object code generated by
    34
     * a source language processor.
    35
     *
    36
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    37
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    38
     * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
    39
     * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
    40
     * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
    41
     * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    42
     * DEALINGS IN THE SOFTWARE. */
    43
    #ifndef INTERNAL_CATCH_UNIQUE_NAME_LINE2
    44
    #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) CASE_UNIQUE_NAME_PREFIX##name##line
    45
    #endif
    46
    #ifndef INTERNAL_CATCH_UNIQUE_NAME_LINE
    47
    #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
    48
    #endif
    49
    #ifndef INTERNAL_CATCH_UNIQUE_NAME
    50
    #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
    51
    #endif
    52
    53
    typedef void (*case_f)(char*, int*);
    54
    55
    void __attribute__((weak)) __test_case_setup(void);
    56
    void __attribute__((weak)) __test_case_teardown(void);
    57
    58
    #define TEST_SETUP() void __test_case_setup(void)
    59
    #define TEST_TEARDOWN() void __test_case_teardown(void)
    60
    61
    #if defined(__ELF__) || defined(__APPLE__)
    62
    // in ELF object format, we can simply query custom section rather than scan through the whole binary memory
    63
    // to find function pointer. We do this whenever possible because in this way, we don't have access error
    64
    // when hooking up with memory checkers such as address sanitizer or valgrind
    65
    typedef struct {
    66
      uint64_t sig_head;
    67
      case_f func;
    68
      char* name;
    69
      char* dir;
    70
      uint64_t sig_tail;
    71
    } case_t;
    72
    73
    #ifdef __ELF__
    74
    #define TEST_CASE(desc) \
    75
    static void __attribute__((used)) INTERNAL_CATCH_UNIQUE_NAME(__test_case_func__) (char* __case_name__, int* __case_result__); \
    76
    static case_t INTERNAL_CATCH_UNIQUE_NAME(__test_case_ctx__) __attribute__((used, section("case_data"), aligned(8))) = { .func = INTERNAL_CATCH_UNIQUE_NAME(__test_case_func__), .sig_head = 0x883253372849284B, .name = desc, .dir = CASE_TEST_DIR, .sig_tail = 0x883253372849284B + 2 }; \
    77
    static void INTERNAL_CATCH_UNIQUE_NAME(__test_case_func__) (char* __case_name__, int* __case_result__)
    78
    #else
    79
    #define TEST_CASE(desc) \
    80
    static void __attribute__((used)) INTERNAL_CATCH_UNIQUE_NAME(__test_case_func__) (char* __case_name__, int* __case_result__); \
    81
    static case_t INTERNAL_CATCH_UNIQUE_NAME(__test_case_ctx__) __attribute__((used, section("__DATA,case_data"), aligned(8))) = { .func = INTERNAL_CATCH_UNIQUE_NAME(__test_case_func__), .sig_head = 0x883253372849284B, .name = desc, .dir = CASE_TEST_DIR, .sig_tail = 0x883253372849284B + 2 }; \
    82
    static void INTERNAL_CATCH_UNIQUE_NAME(__test_case_func__) (char* __case_name__, int* __case_result__)
    83
    #endif
    84
    #else
    85
    typedef struct {
    86
      uint64_t sig_head;
    87
      case_f func;
    88
      char* name;
    89
      char* dir;
    90
      uint64_t sig_tail;
    91
    } case_t;
    92
    93
    #define TEST_CASE(desc) \
    94
    static void __attribute__((used)) INTERNAL_CATCH_UNIQUE_NAME(__test_case_func__) (char* __case_name__, int* __case_result__); \
    95
    static case_t INTERNAL_CATCH_UNIQUE_NAME(__test_case_ctx__) __attribute__((used, aligned(8))) = { .func = INTERNAL_CATCH_UNIQUE_NAME(__test_case_func__), .sig_head = 0x883253372849284B, .name = desc, .dir = CASE_TEST_DIR, .sig_tail = 0x883253372849284B + 2 }; \
    96
    static void INTERNAL_CATCH_UNIQUE_NAME(__test_case_func__) (char* __case_name__, int* __case_result__)
    97
    #endif
    98
    99
    0
    #define ABORT_CASE (*__case_result__) = -1; return;
    100
    101
    1.59k
    #define GUARD_ELSE_RETURN(x) if (872x) {}513 else { (*__case_result__) = -2; return; }359
    102
    103
    100M
    #define REQUIRE(a, err, ...) { \
    104
    100M
    if (!(a308)) \
    105
    0
    { \
    106
    0
      if (isatty(fileno(stdout))) \
    107
    0
        printf("\n\t\033[0;31mREQUIRE\033[0;0m: %s:%d: %s is not true, " err, __FILE__, __LINE__, #a, ##__VA_ARGS__); \
    108
    0
      else \
    109
    0
        printf("\n\tREQUIRE: %s:%d: %s is not true, " err, __FILE__, __LINE__, #a, ##__VA_ARGS__); \
    110
    0
      ABORT_CASE; \
    111
    0
    } }
    112
    113
    102M
    #define REQUIRE_EQ(a, b, err, ...) { \
    114
    102M
    if ((a) != (b)102M) \
    115
    0
    { \
    116
    0
      if (isatty(fileno(stdout))) \
    117
    0
        printf("\n\t\033[0;31mREQUIRE_EQ\033[0;0m: %s:%d: %s(%lg) != %s(%lg), " err, __FILE__, __LINE__, #a, (double)(a), #b, (double)(b), ##__VA_ARGS__); \
    118
    0
      else \
    119
    0
        printf("\n\tREQUIRE_EQ: %s:%d: %s(%lg) != %s(%lg), " err, __FILE__, __LINE__, #a, (double)(a), #b, (double)(b), ##__VA_ARGS__); \
    120
    0
      ABORT_CASE; \
    121
    0
    } }
    122
    123
    135
    #define REQUIRE_ARRAY_EQ(type, a, b, len, err, ...) { \
    124
    135
    int __case_i__; \
    125
    242k
    for (__case_i__ = 0; __case_i__ < (len); __case_i__++242k) \
    126
    242k
      if (((type*)(a))[__case_i__] != ((type*)(b))[__case_i__]) \
    127
    242k
      { \
    128
    0
        if (isatty(fileno(stdout))) \
    129
    0
          printf("\n\t\033[0;31mREQUIRE_ARRAY_EQ\033[0;0m: %s:%d: %s[%d](%lg) != %s[%d](%lg), " err, __FILE__, __LINE__, #a, __case_i__, (double)((type*)(a))[__case_i__], #b, __case_i__, (double)((type*)(b))[__case_i__], ##__VA_ARGS__); \
    130
    0
        else \
    131
    0
          printf("\n\tREQUIRE_ARRAY_EQ: %s:%d: %s[%d](%lg) != %s[%d](%lg), " err, __FILE__, __LINE__, #a, __case_i__, (double)((type*)(a))[__case_i__], #b, __case_i__, (double)((type*)(b))[__case_i__], ##__VA_ARGS__); \
    132
    0
        ABORT_CASE; \
    133
    0
      } }
    134
    135
    3.61k
    #define REQUIRE_EQ_WITH_TOLERANCE(a, b, t, err, ...) { \
    136
    3.61k
    if ((double)((a) - (b18)) > (t) || (double)((a) - (b18)) < -(t)) \
    137
    0
    { \
    138
    0
      if (isatty(fileno(stdout))) \
    139
    0
        printf("\n\t\033[0;31mREQUIRE_EQ_WITH_TOLERANCE\033[0;0m: %s:%d: %s(%lg) != %s(%lg) | +-%lg, " err, __FILE__, __LINE__, #a, (double)(a), #b, (double)(b), (double)(t), ##__VA_ARGS__); \
    140
    0
      else \
    141
    0
        printf("\n\tREQUIRE_EQ_WITH_TOLERANCE: %s:%d: %s(%lg) != %s(%lg) | +-%lg, " err, __FILE__, __LINE__, #a, (double)(a), #b, (double)(b), (double)(t), ##__VA_ARGS__); \
    142
    0
      ABORT_CASE; \
    143
    0
    } }
    144
    145
    313
    #define REQUIRE_ARRAY_EQ_WITH_TOLERANCE(type, a, b, len, t, err, ...) { \
    146
    313
    int __case_i__; \
    147
    386M
    for (__case_i__ = 0; __case_i__ < (len); __case_i__++386M) \
    148
    386M
      if ((double)(((type*)(a))[__case_i__] - ((type*)(b))[__case_i__]) > (t) || (double)(((type*)(a))[__case_i__] - ((type*)(b))[__case_i__]) < -(t)) \
    149
    386M
      { \
    150
    0
        if (isatty(fileno(stdout))) \
    151
    0
          printf("\n\t\033[0;31mREQUIRE_ARRAY_EQ_WITH_TOLERANCE\033[0;0m: %s:%d: %s[%d](%lg) != %s[%d](%lg) | +-%lg, " err, __FILE__, __LINE__, #a, __case_i__, (double)((type*)(a))[__case_i__], #b, __case_i__, (double)((type*)(b))[__case_i__], (double)(t), ##__VA_ARGS__); \
    152
    0
        else \
    153
    0
          printf("\n\tREQUIRE_ARRAY_EQ_WITH_TOLERANCE: %s:%d: %s[%d](%lg) != %s[%d](%lg) | +-%lg, " err, __FILE__, __LINE__, #a, __case_i__, (double)((type*)(a))[__case_i__], #b, __case_i__, (double)((type*)(b))[__case_i__], (double)(t), ##__VA_ARGS__); \
    154
    0
        ABORT_CASE; \
    155
    0
      } }
    156
    157
    12
    #define REQUIRE_NOT_EQ(a, b, err, ...) { \
    158
    12
    if ((a) == (b)) \
    159
    0
    { \
    160
    0
      if (isatty(fileno(stdout))) \
    161
    0
        printf("\n\t\033[0;31mREQUIRE_NOT_EQ\033[0;0m: %s:%d: %s(%lg) == %s(%lg), " err, __FILE__, __LINE__, #a, (double)(a), #b, (double)(b), ##__VA_ARGS__); \
    162
    0
      else \
    163
    0
        printf("\n\tREQUIRE_NOT_EQ: %s:%d: %s(%lg) == %s(%lg), " err, __FILE__, __LINE__, #a, (double)(a), #b, (double)(b), ##__VA_ARGS__); \
    164
    0
      ABORT_CASE; \
    165
    0
    } }
    166
    167
    1
    #define REQUIRE_ARRAY_NOT_EQ(type, a, b, len, err, ...) { \
    168
    1
    int __case_i__; \
    169
    1
    int __flag__ = 0; \
    170
    3
    for (__case_i__ = 0; !__flag__ && __case_i__ < (len)2; __case_i__++2) \
    171
    2
      __flag__ = (((type*)(a))[__case_i__] != ((type*)(b))[__case_i__]); \
    172
    1
    if (!__flag__) \
    173
    0
    { \
    174
    0
      if (isatty(fileno(stdout))) \
    175
    0
        printf("\n\t\033[0;31mREQUIRE_ARRAY_NOT_EQ\033[0;0m: %s:%d: %s[%d](%lg) == %s[%d](%lg), " err, __FILE__, __LINE__, #a, __case_i__, (double)((type*)(a))[__case_i__], #b, __case_i__, (double)((type*)(b))[__case_i__], ##__VA_ARGS__); \
    176
    0
      else \
    177
    0
        printf("\n\tREQUIRE_ARRAY_NOT_EQ: %s:%d: %s[%d](%lg) == %s[%d](%lg), " err, __FILE__, __LINE__, #a, __case_i__, (double)((type*)(a))[__case_i__], #b, __case_i__, (double)((type*)(b))[__case_i__], ##__VA_ARGS__); \
    178
    0
      ABORT_CASE; \
    179
    0
    } }
    180
    181
    4
    #define REQUIRE_NOT_EQ_WITH_TOLERANCE(a, b, t, err, ...) { \
    182
    4
    if ((double)((a) - (b)) <= (t) && (double)((a) - (b)) >= -(t)) \
    183
    0
    { \
    184
    0
      if (isatty(fileno(stdout))) \
    185
    0
        printf("\n\t\033[0;31mREQUIRE_NOT_EQ_WITH_TLERANCE\033[0;0m: %s:%d: %s(%lg) == %s(%lg) | +-%lg, " err, __FILE__, __LINE__, #a, (double)(a), #b, (double)(b), (double)(t), ##__VA_ARGS__); \
    186
    0
      else \
    187
    0
        printf("\n\tREQUIRE_NOT_EQ_WITH_TLERANCE: %s:%d: %s(%lg) == %s(%lg) | +-%lg, " err, __FILE__, __LINE__, #a, (double)(a), #b, (double)(b), (double)(t), ##__VA_ARGS__); \
    188
    0
      ABORT_CASE; \
    189
    0
    } }
    190
    191
    #define REQUIRE_ARRAY_NOT_EQ_WITH_TOLERANCE(type, a, b, len, t, err, ...) { \
    192
    int __case_i__; \
    193
    int __flag__ = 0; \
    194
    for (__case_i__ = 0; !__flag__ && __case_i__ < (len); __case_i__++) \
    195
      __flag__ = ((double)(((type*)(a))[__case_i__] - ((type*)(b))[__case_i__]) > (t) || (double)(((type*)(a))[__case_i__] - ((type*)(b))[__case_i__]) < -(t)); \
    196
    if (!__flag__) \
    197
    { \
    198
      if (isatty(fileno(stdout))) \
    199
        printf("\n\t\033[0;31mREQUIRE_ARRAY_NOT_EQ_WITH_TOLERANCE\033[0;0m: %s:%d: %s[%d](%lg) == %s[%d](%lg) | +-%lg, " err, __FILE__, __LINE__, #a, __case_i__, (double)((type*)(a))[__case_i__], #b, __case_i__, (double)((type*)(b))[__case_i__], (double)(t), ##__VA_ARGS__); \
    200
      else \
    201
        printf("\n\tREQUIRE_ARRAY_NOT_EQ_WITH_TOLERANCE: %s:%d: %s[%d](%lg) == %s[%d](%lg) | +-%lg, " err, __FILE__, __LINE__, #a, __case_i__, (double)((type*)(a))[__case_i__], #b, __case_i__, (double)((type*)(b))[__case_i__], (double)(t), ##__VA_ARGS__); \
    202
      ABORT_CASE; \
    203
    } }
    204
    205
    #endif