Coverage Report

Created: 2024-12-02 18:26

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.12k
#define GUARD_ELSE_RETURN(x) 
if (551
x)
{}400
else
{ (*__case_result__) = -2; return; }151
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
103M
#define REQUIRE_EQ(a, b, err, ...) { \
114
103M
if (
(a) != (b)103M
) \
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
133
#define REQUIRE_ARRAY_EQ(type, a, b, len, err, ...) { \
124
133
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.30k
#define REQUIRE_EQ_WITH_TOLERANCE(a, b, t, err, ...) { \
136
3.30k
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
278
#define REQUIRE_ARRAY_EQ_WITH_TOLERANCE(type, a, b, len, t, err, ...) { \
146
278
int __case_i__; \
147
607M
for (__case_i__ = 0; __case_i__ < (len); 
__case_i__++607M
) \
148
607M
  if ((double)(((type*)(a))[__case_i__] - ((type*)(b))[__case_i__]) > (t) || (double)(((type*)(a))[__case_i__] - ((type*)(b))[__case_i__]) < -(t)) \
149
607M
  { \
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
13
#define REQUIRE_NOT_EQ(a, b, err, ...) { \
158
13
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
2
for (__case_i__ = 0; !__flag__ && 
__case_i__ < (len)1
;
__case_i__++1
) \
171
1
  __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