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