1/* Functionality for reporting test results.
2 Copyright (C) 2016-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#ifndef SUPPORT_CHECK_H
20#define SUPPORT_CHECK_H
21
22#include <sys/cdefs.h>
23#include <stddef.h>
24
25__BEGIN_DECLS
26
27/* Record a test failure, print the failure message to standard output
28 and return 1. */
29#define FAIL_RET(...) \
30 return support_print_failure_impl (__FILE__, __LINE__, __VA_ARGS__)
31
32/* Print the failure message and terminate the process with STATUS.
33 Record a the process as failed if STATUS is neither EXIT_SUCCESS
34 nor EXIT_UNSUPPORTED. */
35#define FAIL_EXIT(status, ...) \
36 support_exit_failure_impl (status, __FILE__, __LINE__, __VA_ARGS__)
37
38/* Record a test failure, print the failure message and terminate with
39 exit status 1. */
40#define FAIL_EXIT1(...) \
41 support_exit_failure_impl (1, __FILE__, __LINE__, __VA_ARGS__)
42
43/* Print failure message and terminate with as unsupported test (exit
44 status of 77). */
45#define FAIL_UNSUPPORTED(...) \
46 support_exit_failure_impl (77, __FILE__, __LINE__, __VA_ARGS__)
47
48/* Record a test failure (but continue executing) if EXPR evaluates to
49 false. */
50#define TEST_VERIFY(expr) \
51 ({ \
52 if (expr) \
53 ; \
54 else \
55 support_test_verify_impl (__FILE__, __LINE__, #expr); \
56 })
57
58/* Record a test failure and exit if EXPR evaluates to false. */
59#define TEST_VERIFY_EXIT(expr) \
60 ({ \
61 if (expr) \
62 ; \
63 else \
64 support_test_verify_exit_impl \
65 (1, __FILE__, __LINE__, #expr); \
66 })
67
68
69
70int support_print_failure_impl (const char *file, int line,
71 const char *format, ...)
72 __attribute__ ((nonnull (1), format (printf, 3, 4)));
73void support_exit_failure_impl (int exit_status,
74 const char *file, int line,
75 const char *format, ...)
76 __attribute__ ((noreturn, nonnull (2), format (printf, 4, 5)));
77void support_test_verify_impl (const char *file, int line,
78 const char *expr);
79void support_test_verify_exit_impl (int status, const char *file, int line,
80 const char *expr)
81 __attribute__ ((noreturn));
82
83/* Record a test failure. This function returns and does not
84 terminate the process. The failure counter is stored in a shared
85 memory mapping, so that failures reported in child processes are
86 visible to the parent process and test driver. This function
87 depends on initialization by an ELF constructor, so it can only be
88 invoked after the test driver has run. Note that this function
89 does not support reporting failures from a DSO. */
90void support_record_failure (void);
91
92/* Static assertion, under a common name for both C++ and C11. */
93#ifdef __cplusplus
94# define support_static_assert static_assert
95#else
96# define support_static_assert _Static_assert
97#endif
98
99/* Compare the two integers LEFT and RIGHT and report failure if they
100 are different. */
101#define TEST_COMPARE(left, right) \
102 ({ \
103 /* + applies the integer promotions, for bitfield support. */ \
104 typedef __typeof__ (+ (left)) __left_type; \
105 typedef __typeof__ (+ (right)) __right_type; \
106 __left_type __left_value = (left); \
107 __right_type __right_value = (right); \
108 int __left_is_positive = __left_value > 0; \
109 int __right_is_positive = __right_value > 0; \
110 /* Prevent use with floating-point types. */ \
111 support_static_assert ((__left_type) 1.0 == (__left_type) 1.5, \
112 "left value has floating-point type"); \
113 support_static_assert ((__right_type) 1.0 == (__right_type) 1.5, \
114 "right value has floating-point type"); \
115 /* Prevent accidental use with larger-than-long long types. */ \
116 support_static_assert (sizeof (__left_value) <= sizeof (long long), \
117 "left value fits into long long"); \
118 support_static_assert (sizeof (__right_value) <= sizeof (long long), \
119 "right value fits into long long"); \
120 /* Compare the value. */ \
121 if (__left_value != __right_value \
122 || __left_is_positive != __right_is_positive) \
123 /* Pass the sign for printing the correct value. */ \
124 support_test_compare_failure \
125 (__FILE__, __LINE__, \
126 #left, __left_value, __left_is_positive, sizeof (__left_type), \
127 #right, __right_value, __right_is_positive, sizeof (__right_type)); \
128 })
129
130/* Internal implementation of TEST_COMPARE. LEFT_POSITIVE and
131 RIGHT_POSITIVE are used to store the sign separately, so that both
132 unsigned long long and long long arguments fit into LEFT_VALUE and
133 RIGHT_VALUE, and the function can still print the original value.
134 LEFT_SIZE and RIGHT_SIZE specify the size of the argument in bytes,
135 for hexadecimal formatting. */
136void support_test_compare_failure (const char *file, int line,
137 const char *left_expr,
138 long long left_value,
139 int left_positive,
140 int left_size,
141 const char *right_expr,
142 long long right_value,
143 int right_positive,
144 int right_size);
145
146
147/* Compare [LEFT, LEFT + LEFT_LENGTH) with [RIGHT, RIGHT +
148 RIGHT_LENGTH) and report a test failure if the arrays are
149 different. LEFT_LENGTH and RIGHT_LENGTH are measured in bytes. If
150 the length is null, the corresponding pointer is ignored (i.e., it
151 can be NULL). The blobs should be reasonably short because on
152 mismatch, both are printed. */
153#define TEST_COMPARE_BLOB(left, left_length, right, right_length) \
154 (support_test_compare_blob (left, left_length, right, right_length, \
155 __FILE__, __LINE__, \
156 #left, #left_length, #right, #right_length))
157
158void support_test_compare_blob (const void *left,
159 unsigned long int left_length,
160 const void *right,
161 unsigned long int right_length,
162 const char *file, int line,
163 const char *left_exp, const char *left_len_exp,
164 const char *right_exp,
165 const char *right_len_exp);
166
167/* Compare the strings LEFT and RIGHT and report a test failure if
168 they are different. Also report failure if one of the arguments is
169 a null pointer and the other is not. The strings should be
170 reasonably short because on mismatch, both are printed. */
171#define TEST_COMPARE_STRING(left, right) \
172 (support_test_compare_string (left, right, __FILE__, __LINE__, \
173 #left, #right))
174
175/* Compare the wide strings LEFT and RIGHT and report a test failure
176 if they are different. Also report failure if one of the arguments
177 is a null pointer and the other is not. The strings should be
178 reasonably short because on mismatch, both are printed. */
179#define TEST_COMPARE_STRING_WIDE(left, right) \
180 (support_test_compare_string_wide (left, right, __FILE__, __LINE__, \
181 #left, #right))
182
183void support_test_compare_string (const char *left, const char *right,
184 const char *file, int line,
185 const char *left_expr,
186 const char *right_expr);
187
188void support_test_compare_string_wide (const wchar_t *left,
189 const wchar_t *right,
190 const char *file, int line,
191 const char *left_expr,
192 const char *right_expr);
193
194/* Internal function called by the test driver. */
195int support_report_failure (int status)
196 __attribute__ ((weak, warn_unused_result));
197
198/* Internal function used to test the failure recording framework. */
199void support_record_failure_reset (void);
200
201/* Returns true or false depending on whether there have been test
202 failures or not. */
203int support_record_failure_is_failed (void);
204
205__END_DECLS
206
207#endif /* SUPPORT_CHECK_H */
208

source code of glibc/support/check.h