1 /* Functionality for reporting test results.
2    Copyright (C) 2016-2022 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 
70 int support_print_failure_impl (const char *file, int line,
71                                 const char *format, ...)
72   __attribute__ ((nonnull (1), format (printf, 3, 4)));
73 void 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)));
77 void support_test_verify_impl (const char *file, int line,
78                                const char *expr);
79 void 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.  */
90 void 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.  */
136 void 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 
158 void 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 
183 void 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 
188 void 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.  */
195 int support_report_failure (int status)
196   __attribute__ ((weak, warn_unused_result));
197 
198 /* Internal function used to test the failure recording framework.  */
199 void support_record_failure_reset (void);
200 
201 /* Returns true or false depending on whether there have been test
202    failures or not.  */
203 int support_record_failure_is_failed (void);
204 
205 __END_DECLS
206 
207 #endif /* SUPPORT_CHECK_H */
208