| /* | 
 |  This Software is provided under the Zope Public License (ZPL) Version 2.1. | 
 |  | 
 |  Copyright (c) 2009, 2010 by the mingw-w64 project | 
 |  | 
 |  See the AUTHORS file for the list of contributors to the mingw-w64 project. | 
 |  | 
 |  This license has been certified as open source. It has also been designated | 
 |  as GPL compatible by the Free Software Foundation (FSF). | 
 |  | 
 |  Redistribution and use in source and binary forms, with or without | 
 |  modification, are permitted provided that the following conditions are met: | 
 |  | 
 |    1. Redistributions in source code must retain the accompanying copyright | 
 |       notice, this list of conditions, and the following disclaimer. | 
 |    2. Redistributions in binary form must reproduce the accompanying | 
 |       copyright notice, this list of conditions, and the following disclaimer | 
 |       in the documentation and/or other materials provided with the | 
 |       distribution. | 
 |    3. Names of the copyright holders must not be used to endorse or promote | 
 |       products derived from this software without prior written permission | 
 |       from the copyright holders. | 
 |    4. The right to distribute this software or to use it for any purpose does | 
 |       not give you the right to use Servicemarks (sm) or Trademarks (tm) of | 
 |       the copyright holders.  Use of them is covered by separate agreement | 
 |       with the copyright holders. | 
 |    5. If any files are modified, you must cause the modified files to carry | 
 |       prominent notices stating that you changed the files and the date of | 
 |       any change. | 
 |  | 
 |  Disclaimer | 
 |  | 
 |  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED | 
 |  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
 |  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | 
 |  EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, | 
 |  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
 |  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  | 
 |  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | 
 |  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 
 |  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | 
 |  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
 | */ | 
 |  | 
 | /* Testsuite functions for the complex functions of C99.  */ | 
 | #ifndef _NEWCOMPLEX_TEST_H | 
 | #define _NEWCOMPLEX_TEST_H | 
 |  | 
 | /* Support printing of long doubles.  */ | 
 | #define __USE_MINGW_ANSI_STDIO 1 | 
 | #include <stdio.h> | 
 | #include <math.h> | 
 | #include <complex.h> | 
 |  | 
 | /* Default to double types.  */ | 
 | #if !(defined (_NEW_COMPLEX_FLOAT) || defined (_NEW_COMPLEX_DOUBLE) || defined (_NEW_COMPLEX_LDOUBLE)) | 
 | #define _NEW_COMPLEX_DOUBLE 1 | 
 | #endif | 
 |  | 
 | /* Grab the internals for things like __FLT_PI, etc.  */ | 
 | #include "complex_internal.h" | 
 |  | 
 | /* Declare comparisons etc.  */ | 
 | #if defined(_NEW_COMPLEX_DOUBLE) | 
 | # define __FLT_CMP	compare_dbl | 
 | # define __FLT_CCMP	compare_cdbl | 
 | # define __FLT_DELTA	(2.0 * __DBL_EPSILON__) | 
 | # define __FLT_FMT	"%0.32g" | 
 | #elif defined (_NEW_COMPLEX_FLOAT) | 
 | # define __FLT_CMP	compare_flt | 
 | # define __FLT_CCMP	compare_cflt | 
 | # define __FLT_DELTA	(2.0F * __FLT_EPSILON__) | 
 | # define __FLT_FMT	 "%0.32g" | 
 | #elif defined (_NEW_COMPLEX_LDOUBLE) | 
 | # define __FLT_CMP	compare_ldbl | 
 | # define __FLT_CCMP	compare_cldbl | 
 | # define __FLT_DELTA	(2.0L * __LDBL_EPSILON__) | 
 | # define __FLT_FMT	 "%0.32Lg" | 
 | #endif | 
 |  | 
 | struct complex_test | 
 | { | 
 |   /* The input value to the complex function */ | 
 |   __FLT_TYPE input_r; | 
 |   __FLT_TYPE input_i; | 
 |   /* The expected value from the complex function */ | 
 |   __FLT_TYPE expected_r; | 
 |   __FLT_TYPE expected_i; | 
 |   /* Some C99 signs are +/-.  When these are true, don't compare signs */ | 
 |   int real_sign_dontcare; | 
 |   int imag_sign_dontcare; | 
 | }; | 
 |  | 
 | /* Definition of the function under test.  */ | 
 | typedef __FLT_TYPE complex (*complex_function)(__FLT_TYPE complex z); | 
 | typedef __FLT_TYPE         (*real_function)(__FLT_TYPE complex z); | 
 |  | 
 | /* Some possible behaviors of the function.  */ | 
 | /* func (conj (z)) = conj (func (z))  */ | 
 | #define FUNC_BEHAVIOR_CONJ 0x0001 | 
 | /* func (-z) = -func (z)  */ | 
 | #define FUNC_BEHAVIOR_ODD  0x0002 | 
 | /* func (-z) = func (z)  */ | 
 | #define FUNC_BEHAVIOR_EVEN 0x0004 | 
 |  | 
 | /* Structure to hold info about the complex function.  */ | 
 | struct test_func_desc | 
 | { | 
 |   const char *fname; | 
 |   complex_function complex_test; | 
 |   real_function    real_test; | 
 |   int              behavior; | 
 | }; | 
 |  | 
 | /** | 
 |  * Compares expected and test values with a delta tolerance. | 
 |  * 0 for pass, 1 for fail. | 
 |  * TODO: | 
 |  * Tune comparison precision | 
 |  **/ | 
 |  | 
 | static int | 
 | __FLT_CMP (__FLT_TYPE expected, __FLT_TYPE in, int sign_dontcare) | 
 | { | 
 |   int bad = 0; | 
 |   if (isnan (expected) || isnan (in)) | 
 |     { | 
 |       /* NaN comparisons */ | 
 |       bad = isnan (expected) != isnan (in); | 
 |     } | 
 |   else if (isfinite (expected) && isfinite (in)) | 
 |     { | 
 |       /* Finite value tests */ | 
 |       if (expected == 0 && in == 0) | 
 | 	{ | 
 | 	  /* Signed zero comparison */ | 
 | 	  bad = (sign_dontcare) ? 0 : signbit (expected) != signbit (in); | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  bad = (expected > in) ? | 
 | 		((expected - in) > __FLT_DELTA) : | 
 | 		((in - expected) > __FLT_DELTA); | 
 | 	} | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Either expected or in is an infinite */ | 
 |       bad = !isinf(expected) || !isinf(in); | 
 |       if (!bad && !sign_dontcare) | 
 | 	bad =  signbit (expected) != signbit (in); | 
 |     } | 
 |  | 
 |   return bad; | 
 | } | 
 |  | 
 | static int | 
 | __FLT_CCMP (complex __FLT_TYPE expected, | 
 | 	    complex __FLT_TYPE in, | 
 | 	    int real_sign_dontcare, | 
 | 	    int imag_sign_dontcare) | 
 | { | 
 |   return (__FLT_CMP (__FLT_ABI(creal)(expected), __FLT_ABI(creal)(in), real_sign_dontcare) || | 
 | 	  __FLT_CMP (__FLT_ABI(cimag)(expected), __FLT_ABI(cimag)(in), imag_sign_dontcare)); | 
 | } | 
 |  | 
 | /* Runs comparison and (DEBUG) print error. | 
 |    returns 1 on fail, 0 on success.  */ | 
 | static int | 
 | error_check_test (const struct test_func_desc *fdesc, | 
 | 		  const char* testdescription, | 
 | 		  int testindex, | 
 | 		  __FLT_TYPE complex test, | 
 | 		  __FLT_TYPE complex expected, | 
 | 		  int real_sign_dontcare, | 
 | 		  int imag_sign_dontcare) | 
 | { | 
 |   int bad = 0; | 
 |   __FLT_TYPE complex actual; | 
 |   if (fdesc->complex_test) | 
 |     { | 
 |       actual = fdesc->complex_test (test); | 
 |       bad = __FLT_CCMP (expected, actual, real_sign_dontcare, imag_sign_dontcare); | 
 |       if (bad) | 
 | 	{ | 
 | 	  printf("%s %s test index %d failed on input " __FLT_FMT " + " __FLT_FMT "i.\n" | 
 | 		"\tExpected: " __FLT_FMT " + " __FLT_FMT "i\n" | 
 | 		"\tActual: " __FLT_FMT " + " __FLT_FMT "i (epsilon=" __FLT_FMT ")\n", | 
 | 		fdesc->fname, testdescription, testindex, | 
 | 		__FLT_ABI(creal) (test),    __FLT_ABI(cimag) (test), | 
 | 		__FLT_ABI(creal) (expected), __FLT_ABI(cimag) (expected), | 
 | 		__FLT_ABI(creal) (actual),   __FLT_ABI(cimag) (actual), | 
 | 		__FLT_DELTA); | 
 | 	} | 
 |     } | 
 |   else | 
 |     { | 
 |       __real__ actual = fdesc->real_test (test); | 
 |       bad = __FLT_CMP (__real__ expected, actual, real_sign_dontcare); | 
 |       if (bad) | 
 | 	{ | 
 | 	  printf("%s %s test index %d failed on input " __FLT_FMT " + " __FLT_FMT "i.\n" | 
 | 		"\tExpected: " __FLT_FMT "\n" | 
 | 		"\tActual: " __FLT_FMT " (epsilon=" __FLT_FMT ")\n", | 
 | 		fdesc->fname, testdescription, testindex, | 
 | 		__FLT_ABI(creal) (test),    __FLT_ABI(cimag) (test), | 
 | 		__FLT_ABI(creal) (expected), | 
 | 		__FLT_ABI(creal) (actual), | 
 | 		__FLT_DELTA); | 
 | 	} | 
 |     } | 
 |  | 
 |   return bad; | 
 | } | 
 |  | 
 | /* Tests of conjugates, function should satisfy | 
 |    func (conj (z)) = conj (func (z)).  func (conj (z)) should return | 
 |    the conj of the expected, since expected is the expected result of | 
 |    func (z).  */ | 
 | static int | 
 | conjugate_tests (const struct test_func_desc *fdesc, | 
 | 		 int testindex, | 
 | 		 __FLT_TYPE complex test, | 
 | 		 __FLT_TYPE complex expected, | 
 | 		 int real_sign_dontcare, | 
 | 		 int imag_sign_dontcare) | 
 | { | 
 |   int ret = 0; | 
 |  | 
 |   /* Conjugate test 1: verify result of func (conj (z)) is conj (expected) */ | 
 |   __FLT_TYPE complex ctest =    __FLT_ABI(conj) (test); | 
 |   __FLT_TYPE complex cexpected = __FLT_ABI(conj) (expected); | 
 |  | 
 |   ret |= error_check_test (fdesc, "Congugate of expected", testindex, ctest, cexpected, | 
 | 			  real_sign_dontcare, imag_sign_dontcare); | 
 |   return ret; | 
 | } | 
 |  | 
 | /* Tests of odd functions, function should satisfy | 
 |    func (-z) = -func (z).  func (-z) should result in the -expected result, | 
 |    since expected is the expected result of func (z).  */ | 
 | static int | 
 | odd_tests (const struct test_func_desc *fdesc, | 
 | 	   int testindex, | 
 | 	   __FLT_TYPE complex test, | 
 | 	   __FLT_TYPE complex expected, | 
 | 	   int real_sign_dontcare, | 
 | 	   int imag_sign_dontcare) | 
 | { | 
 |   int ret = 0; | 
 |  | 
 |   /* Oddness test 1: verify result of func (-z) is -expected */ | 
 |   __FLT_TYPE complex ctest =    -test; | 
 |   __FLT_TYPE complex cexpected = -expected; | 
 |  | 
 |   ret |= error_check_test (fdesc, "Oddness", testindex, ctest, cexpected, | 
 | 			  real_sign_dontcare, imag_sign_dontcare); | 
 |  | 
 |   /* Need to do conjugate of the odd values as well */ | 
 |   ret |= conjugate_tests(fdesc, testindex, ctest, cexpected, real_sign_dontcare, | 
 | 			imag_sign_dontcare); | 
 |  | 
 |   return ret; | 
 | } | 
 |  | 
 | /* Tests of even functions, function should satisfy | 
 |    func (-z) = func (z).  func (-z) should result in the expected result, | 
 |    since expected is the expected result of func (z).  */ | 
 | static int | 
 | even_tests (const struct test_func_desc *fdesc, | 
 | 	   int testindex, | 
 | 	   __FLT_TYPE complex test, | 
 | 	   __FLT_TYPE complex expected, | 
 | 	   int real_sign_dontcare, | 
 | 	   int imag_sign_dontcare) | 
 | { | 
 |   int ret = 0; | 
 |  | 
 |   /* Evenness test 1: verify result of func (-z) is expected */ | 
 |   __FLT_TYPE complex ctest =    -test; | 
 |   __FLT_TYPE complex cexpected = expected; | 
 |  | 
 |   ret |= error_check_test (fdesc, "Evenness", testindex, ctest, cexpected, | 
 | 			  real_sign_dontcare, imag_sign_dontcare); | 
 |  | 
 |   /* Need to do conjugate of the even values as well */ | 
 |   ret |= conjugate_tests(fdesc, testindex, ctest, cexpected, real_sign_dontcare, | 
 | 			imag_sign_dontcare); | 
 |   return ret; | 
 | } | 
 |  | 
 | /* Actually run the tests.  */ | 
 | static int | 
 | runtests (const struct test_func_desc *testfunc, | 
 | 	  const struct complex_test *testarray, | 
 | 	  int testcount) | 
 | { | 
 |   int i; | 
 |   int ret = 0; | 
 |  | 
 |   for (i = 0; i < testcount; i++) | 
 |     { | 
 |       __FLT_TYPE complex test; | 
 |       __FLT_TYPE complex expected; | 
 |       __real__ test = testarray[i].input_r; | 
 |       __imag__ test = testarray[i].input_i; | 
 |       __real__ expected = testarray[i].expected_r; | 
 |       __imag__ expected = testarray[i].expected_i; | 
 |  | 
 |       /* Main test --- specified in Annex G, et al. */ | 
 |       ret |= error_check_test (testfunc, "Annex G", i, test, expected, | 
 | 		testarray[i].real_sign_dontcare, testarray[i].imag_sign_dontcare); | 
 |  | 
 |       if (testfunc->behavior & FUNC_BEHAVIOR_CONJ) | 
 | 	{ | 
 | 	  ret |= conjugate_tests (testfunc, i, test, expected, | 
 | 		 testarray[i].real_sign_dontcare, testarray[i].imag_sign_dontcare); | 
 | 	} | 
 |  | 
 |       if (testfunc->behavior & FUNC_BEHAVIOR_ODD) | 
 | 	{ | 
 | 	  ret |= odd_tests (testfunc, i, test, expected, | 
 | 		 testarray[i].real_sign_dontcare, testarray[i].imag_sign_dontcare); | 
 | 	} | 
 |  | 
 |       if (testfunc->behavior & FUNC_BEHAVIOR_EVEN) | 
 | 	{ | 
 | 	  ret |= even_tests (testfunc, i, test, expected, | 
 | 		 testarray[i].real_sign_dontcare, testarray[i].imag_sign_dontcare); | 
 | 	} | 
 |     } | 
 |  | 
 |   return ret; | 
 | } | 
 |  | 
 | #define __FLT_STRING(x) #x | 
 | #define __FLT_STRINGIFY(x) __FLT_STRING(x) | 
 |  | 
 | /** | 
 |  * Defines the test function with a variable name to pass to RUN_TESTS. | 
 |  * varname is the varname to use. | 
 |  * funcame is the function to test. | 
 |  * behavior is the flags of how the function behaves. | 
 |  */ | 
 | #define DEFINE_TEST_FUNCTION(varname, funcname, behavior)	\ | 
 |   struct test_func_desc varname =				\ | 
 |   {								\ | 
 |     __FLT_STRINGIFY(__FLT_ABI(funcname)),			\ | 
 |     __FLT_ABI(funcname),					\ | 
 |     NULL,							\ | 
 |     behavior							\ | 
 |   } | 
 |  | 
 | /** | 
 |  * Defines the test function with a variable name to pass to RUN_TESTS. | 
 |  * This version is for functions that return a real value. | 
 |  * varname is the varname to use. | 
 |  * funcame is the function to test. | 
 |  * behavior is the flags of how the function behaves. | 
 |  */ | 
 | #define DEFINE_TEST_FUNCTION_REAL(varname, funcname, behavior)	\ | 
 |   struct test_func_desc varname =					\ | 
 |   {									\ | 
 |     __FLT_STRINGIFY(__FLT_ABI(funcname)),				\ | 
 |     NULL,								\ | 
 |     __FLT_ABI(funcname),						\ | 
 |     behavior								\ | 
 |   } | 
 |  | 
 |  | 
 | /* Do not use semicolons with these macros.  */ | 
 |  | 
 | /** | 
 |  * Starts a declaration of tests, with a variable name. | 
 |  */ | 
 | #define TESTS_START(v) const struct complex_test v[] = { | 
 |  | 
 | /** | 
 |  * Starts a declaration of tests, with a default variable name, for use with | 
 |  * RUN_DEFAULT_TESTS. | 
 |  */ | 
 | #define DEFAULT_TESTS_START TESTS_START(_default_tests) | 
 |  | 
 | /** | 
 |  * Macro to fill a complex_test structure with values while inside a | 
 |  * TESTS block. | 
 |  */ | 
 | #define DEFINE_TEST(input_r, input_i, expected_r, expected_i, real_sign_dontcare, imag_sign_dontcare)	\ | 
 |   { input_r, input_i, expected_r, expected_i, real_sign_dontcare, imag_sign_dontcare }, | 
 |  | 
 | /** | 
 |  * Closes a test block opened with the TESTS_START macros. | 
 |  */ | 
 | #define TESTS_END }; | 
 |  | 
 | /** | 
 |  * Runs the tests specified in testarray using the specified test function | 
 |  * definition. | 
 |  * testfunc is the function definition specification defined by one of the | 
 |  * DEFINE_TEST_FUNCTION macros. | 
 |  * testarray is the test array defined by a TESTS_START macro. | 
 |  */ | 
 | #define RUN_TESTS(testfunc, testarray) \ | 
 |   (runtests(&testfunc, testarray, (sizeof (testarray) / sizeof (*testarray)))) | 
 |  | 
 | /** | 
 |  * Runs the tests specified in testarray using the test function | 
 |  * definition declared with DEFINE_DEFAULT_TEST_FUNCTION macros. | 
 |  * funcname is the function name passed to the DEFAULT_TEST_FUNCTION* macro. | 
 |  * testarray is the test array defined by the TESTS_START macro. | 
 |  */ | 
 | #define RUN_FUNCTION_TESTS(funcname, testarray) \ | 
 |   RUN_TESTS(_test_##funcname, testarray) | 
 |  | 
 | /** | 
 |  * Runs the tests specified by DEFAULT_TESTS testarray using the test function | 
 |  * definition declared with DEFINE_DEFAULT_TEST_FUNCTION macros. | 
 |  * funcname is the function name passed to the DEFAULT_TEST_FUNCTION* macro. | 
 |  */ | 
 | #define RUN_DEFAULT_TESTS(funcname) \ | 
 |   RUN_TESTS(_test_##funcname, _default_tests) | 
 |  | 
 | /** | 
 |  * Default test functions available. | 
 |  */ | 
 |  | 
 | /** | 
 |  * Defines a test function with a default variable name for use with the | 
 |  * RUN_DEFAULT_TESTS macro. | 
 |  * funcname is the function family to test. | 
 |  * behavior is the function's behavior. | 
 |  */ | 
 | #define _DEFINE_DEFAULT_TEST_FUNCTION(funcname, behavior) \ | 
 | 	DEFINE_TEST_FUNCTION(_test_##funcname, funcname, behavior) | 
 |  | 
 | /** | 
 |  * Defines a test function with a default variable name for use with the | 
 |  * RUN_DEFAULT_TESTS macro.  This version is for functions that return | 
 |  * a real value. | 
 |  * funcname is the function family to test. | 
 |  * behavior is the function's behavior. | 
 |  */ | 
 | #define _DEFINE_DEFAULT_TEST_FUNCTION_REAL(funcname, behavior) \ | 
 | 	DEFINE_TEST_FUNCTION_REAL(_test_##funcname, funcname, behavior) | 
 |  | 
 | #endif  /* _NEWCOMPLEX_TEST_H */ |