1  /* Functionality for reporting test results.
       2     Copyright (C) 2016-2023 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 */