Index: configure =================================================================== --- configure (Revision 59539) +++ configure (Arbeitskopie) @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 59484 . +# From configure.in Revision: 59533 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.6. # @@ -20368,6 +20368,9 @@ fi +# ************************************ +# * Check for mathematical functions * +# ************************************ # check for hypot() in math library LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" @@ -20473,6 +20476,113 @@ done + + + + + + + + + + + + + +for ac_func in copysign erf erfc isnan isinf j0 j1 jn lgamma_r y0 y1 yn +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + LIBS=$LIBS_SAVE # check for wchar.h Index: Include/pyport.h =================================================================== --- Include/pyport.h (Revision 59539) +++ Include/pyport.h (Arbeitskopie) @@ -349,6 +349,17 @@ #define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE) #endif +/* High precision defintion of pi and e (Euler) + * The values are taken from libc6's math.h. + */ +#ifndef Py_MATH_PI +#define Py_MATH_PI 3.1415926535897932384626433832795029L +#endif + +#ifndef Py_MATH_E +#define Py_MATH_E 2.7182818284590452353602874713526625L +#endif + /* Py_IS_NAN(X) * Return 1 if float or double arg is a NaN, else 0. * Caution: @@ -358,8 +369,12 @@ * a platform where it doesn't work. */ #ifndef Py_IS_NAN +#ifdef HAVE_ISNAN +#define Py_IS_NAN(X) isnan(X) +#else #define Py_IS_NAN(X) ((X) != (X)) #endif +#endif /* Py_IS_INFINITY(X) * Return 1 if float or double arg is an infinity, else 0. @@ -370,8 +385,12 @@ * Override in pyconfig.h if you have a better spelling on your platform. */ #ifndef Py_IS_INFINITY +#ifdef HAVE_ISINF +#define Py_IS_INFINITY(X) isinf(X) +#else #define Py_IS_INFINITY(X) ((X) && (X)*0.5 == (X)) #endif +#endif /* Py_IS_FINITE(X) * Return 1 if float or double arg is neither infinite nor NAN, else 0. Index: configure.in =================================================================== --- configure.in (Revision 59539) +++ configure.in (Arbeitskopie) @@ -2974,10 +2974,16 @@ fi], [AC_MSG_RESULT(default LIBC="$LIBC")]) +# ************************************ +# * Check for mathematical functions * +# ************************************ # check for hypot() in math library LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" AC_REPLACE_FUNCS(hypot) + +AC_CHECK_FUNCS(copysign erf erfc isnan isinf j0 j1 jn lgamma_r y0 y1 yn) + LIBS=$LIBS_SAVE # check for wchar.h Index: PC/pyconfig.h =================================================================== --- PC/pyconfig.h (Revision 59539) +++ PC/pyconfig.h (Arbeitskopie) @@ -416,6 +416,21 @@ /* Define to `int' if doesn't define. */ /* #undef gid_t */ +/* Define to 1 if you have the `isinf' function. */ +#define HAVE_ISINF 1 + +/* Define to 1 if you have the `isnan' function. */ +#define HAVE_ISNAN 1 + +/* Define to 1 if you have the `j0' function. */ +#define HAVE_J0 1 + +/* Define to 1 if you have the `j1' function. */ +#define HAVE_J1 1 + +/* Define to 1 if you have the `jn' function. */ +#define HAVE_JN 1 + /* Define if your struct tm has tm_zone. */ /* #undef HAVE_TM_ZONE */ @@ -521,6 +536,9 @@ /* Define if you have clock. */ /* #define HAVE_CLOCK */ +/* Define to 1 if you have the `copysign' function. */ +#define HAVE_COPYSIGN 1 + /* Define when any dynamic module loading is enabled */ #define HAVE_DYNAMIC_LOADING @@ -674,6 +692,15 @@ /* Define if the compiler provides a wchar.h header file. */ #define HAVE_WCHAR_H 1 +/* Define to 1 if you have the `y0' function. */ +#define HAVE_Y0 1 + +/* Define to 1 if you have the `y1' function. */ +#define HAVE_Y1 1 + +/* Define to 1 if you have the `yn' function. */ +#define HAVE_YN 1 + /* Define if you have the dl library (-ldl). */ /* #undef HAVE_LIBDL */ Index: Lib/test/test_math.py =================================================================== --- Lib/test/test_math.py (Revision 59539) +++ Lib/test/test_math.py (Arbeitskopie) @@ -203,6 +203,83 @@ self.ftest('tanh(0)', math.tanh(0), 0) self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0) + + def testBessel_first(self): + if not hasattr(math, 'j0'): + return + for z in 2.4048255576957727, 5.5200781102863106, 8.6537279129110122: + self.assertAlmostEqual(math.j0(z), 0) + self.assertAlmostEqual(math.jn(0, z), 0) + self.assertAlmostEqual(math.j0(0.), 1) + self.assert_(math.j0(4.) < 0) + for z in 3.8317059702075123, 7.0155866698156122, 10.173468135062722: + self.assertAlmostEqual(math.j1(z), 0) + self.assertAlmostEqual(math.jn(1, z), 0) + self.assert_(math.j1(1.) > 0) + self.assert_(math.j0(5.5) < 0) + for z in 5.1356223018406826, 8.4172441403998629, 11.619841172149059: + self.assertAlmostEqual(math.jn(2, z), 0) + self.assert_(math.jn(2 ,1.) > 0) + self.assert_(math.jn(2, 7.) < 0) + + def testBessel_second(self): + if not hasattr(math, 'y0'): + return + for z in 0.89357696627916752, 3.9576784193148579, 7.0860510603017727: + self.assertAlmostEqual(math.y0(z), 0) + self.assertAlmostEqual(math.yn(0, z), 0) + for z in 2.1971413260310170, 5.4296810407941351, 8.5960058683311689: + self.assertAlmostEqual(math.y1(z), 0) + self.assertAlmostEqual(math.yn(1, z), 0) + for z in 3.3842417671495935, 6.7938075132682675, 10.023477979360038: + self.assertAlmostEqual(math.yn(2, z), 0) + + def testLgamma(self): + if not hasattr(math, 'lgamma'): + return + self.assertEqual(math.lgamma(1.), (0.0, 1)) + gamma, sign = math.lgamma(1.2) + self.assertAlmostEqual(gamma, -0.0853740900) + self.assertEqual(sign, 1) + self.assertRaises(ValueError, math.lgamma, 0.) + + def testErf(self): + if not hasattr(math, 'erf'): + return + self.assertEqual(math.erf(0.), 0.) + self.assertAlmostEqual(math.erf(6.), 1.) + + def testErfc(self): + if not hasattr(math, 'erfc'): + return + self.assertEqual(math.erfc(0.), 1.) + self.assertAlmostEqual(math.erfc(10.), 0.) + + def testSign(self): + self.assertEqual(math.sign(0), 0) + self.assertEqual(math.sign(-2), -1) + self.assertEqual(math.sign(+2), 1) + self.assertEqual(math.sign(0.), 1) + self.assertEqual(math.sign(-0.), -1) + self.assertEqual(math.sign(-2.), -1) + self.assertEqual(math.sign(+2.), 1) + + def testIsnan(self): + self.assert_(math.isnan(float("nan"))) + self.assert_(math.isnan(float("inf")* 0.)) + self.failIf(math.isnan(float("inf"))) + self.failIf(math.isnan(0.)) + self.failIf(math.isnan(1.)) + + def testIsinf(self): + self.assert_(math.isinf(float("inf"))) + self.assert_(math.isinf(float("-inf"))) + self.assert_(math.isinf(1E400)) + self.assert_(math.isinf(-1E400)) + self.failIf(math.isinf(float("nan"))) + self.failIf(math.isinf(0.)) + self.failIf(math.isinf(1.)) + # RED_FLAG 16-Oct-2000 Tim # While 2.0 is more consistent about exceptions than previous releases, it # still fails this part of the test on some platforms. For now, we only @@ -247,3 +324,4 @@ if __name__ == '__main__': test_main() + Index: Modules/mathmodule.c =================================================================== --- Modules/mathmodule.c (Revision 59539) +++ Modules/mathmodule.c (Arbeitskopie) @@ -86,6 +86,29 @@ return PyFloat_FromDouble(x); } +static PyObject * +math_2n(PyObject *args, double (*func) (int, double), char *funcname) +{ + PyObject *oi, *ox; + long i; + double x; + if (! PyArg_UnpackTuple(args, funcname, 2, 2, &oi, &ox)) + return NULL; + i = PyInt_AsLong(oi); + x = PyFloat_AsDouble(ox); + if ((i == -1 || x == -1.0) && PyErr_Occurred()) + return NULL; + errno = 0; + PyFPE_START_PROTECT("in math_2", return 0) + x = (*func)(i, x); + PyFPE_END_PROTECT(x) + Py_SET_ERRNO_ON_MATH_ERROR(x); + if (errno && is_error(x)) + return NULL; + else + return PyFloat_FromDouble(x); +} + #define FUNC1(funcname, func, docstring) \ static PyObject * math_##funcname(PyObject *self, PyObject *args) { \ return math_1(args, func); \ @@ -97,6 +120,11 @@ return math_2(args, func, #funcname); \ }\ PyDoc_STRVAR(math_##funcname##_doc, docstring); +#define FUNC2n(funcname, func, docstring) \ + static PyObject * math_##funcname(PyObject *self, PyObject *args) { \ + return math_2n(args, func, #funcname); \ + }\ + PyDoc_STRVAR(math_##funcname##_doc, docstring); FUNC1(acos, acos, "acos(x)\n\nReturn the arc cosine (measured in radians) of x.") @@ -114,6 +142,15 @@ "cos(x)\n\nReturn the cosine of x (measured in radians).") FUNC1(cosh, cosh, "cosh(x)\n\nReturn the hyperbolic cosine of x.") +#ifdef HAVE_ERF +FUNC1(erf, erf, + "erf(x)\n\nReturn the error function of x.") +#endif +#ifdef HAVE_ERFC +FUNC1(erfc, erfc, + "erfc(x)\n\nReturn the error function of 1-erf(x) in a way that \n\ +avoids rounding errors for large x.") +#endif FUNC1(exp, exp, "exp(x)\n\nReturn e raised to the power of x.") FUNC1(fabs, fabs, @@ -126,6 +163,18 @@ " x % y may differ.") FUNC2(hypot, hypot, "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).") +#ifdef HAVE_J0 +FUNC1(j0, j0, + "j0(x)\n\nReturn Bessel functions of x of the 1st kind of order 0.") +#endif +#ifdef HAVE_J1 +FUNC1(j1, j1, + "j1(x)\n\nReturn Bessel functions of x of the 1st kind of order 1.") +#endif +#ifdef HAVE_JN +FUNC2n(jn, jn, + "jn(n, x)\n\nReturn Bessel functions of x of the 1st kind of order n.") +#endif FUNC2(pow, pow, "pow(x,y)\n\nReturn x**y (x to the power of y).") FUNC1(sin, sin, @@ -138,6 +187,18 @@ "tan(x)\n\nReturn the tangent of x (measured in radians).") FUNC1(tanh, tanh, "tanh(x)\n\nReturn the hyperbolic tangent of x.") +#ifdef HAVE_Y0 +FUNC1(y0, y0, + "j0(x)\n\nReturn Bessel functions of x of the 2nd kind of order 0.") +#endif +#ifdef HAVE_Y1 +FUNC1(y1, y1, + "j1(x)\n\nReturn Bessel functions of x of the 2nd kind of order 1.") +#endif +#ifdef HAVE_YN +FUNC2n(yn, yn, + "jn(n, x)\n\nReturn Bessel functions of x of the 2nd kind of order n.") +#endif static PyObject * math_frexp(PyObject *self, PyObject *arg) @@ -277,9 +338,8 @@ PyDoc_STRVAR(math_log10_doc, "log10(x) -> the base 10 logarithm of x."); -/* XXX(nnorwitz): Should we use the platform M_PI or something more accurate - like: 3.14159265358979323846264338327950288 */ -static const double degToRad = 3.141592653589793238462643383 / 180.0; +static const double degToRad = Py_MATH_PI / 180.0; +static const double radToDeg = 180.0 / Py_MATH_PI; static PyObject * math_degrees(PyObject *self, PyObject *arg) @@ -287,7 +347,7 @@ double x = PyFloat_AsDouble(arg); if (x == -1.0 && PyErr_Occurred()) return NULL; - return PyFloat_FromDouble(x / degToRad); + return PyFloat_FromDouble(x * radToDeg); } PyDoc_STRVAR(math_degrees_doc, @@ -305,6 +365,110 @@ PyDoc_STRVAR(math_radians_doc, "radians(x) -> converts angle x from degrees to radians"); +static PyObject * +math_isnan(PyObject *self, PyObject *arg) +{ + double x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + return PyBool_FromLong((long)Py_IS_NAN(x)); +} + +PyDoc_STRVAR(math_isnan_doc, +"isnan(x) -> bool\n\ +Checks if float x is not a number (NaN)"); + +static PyObject * +math_isinf(PyObject *self, PyObject *arg) +{ + double x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + return PyBool_FromLong((long)Py_IS_INFINITY(x)); +} + +PyDoc_STRVAR(math_isinf_doc, +"isinf(x) -> bool\n\ +Checks if float x is infinite (positive or negative)"); + +static PyObject * +math_sign(PyObject *self, PyObject *arg) +{ + int result = -2; + if (PyInt_Check(arg)) { + long l = PyInt_AsLong(arg); + if (l == -1.0 && PyErr_Occurred()) + return NULL; + result = l > 0 ? 1 : + l < 0 ? -1 : 0; + + } + if (PyLong_Check(arg)) { + result = _PyLong_Sign(arg); + } + else if (PyFloat_Check(arg)) { + double x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) + return NULL; +#ifdef HAVE_COPYSIGN + result = (int)copysign(1., x); +#else + result = x > 0. ? 1 : + x < 0. ? -1 : 0; +#endif + } + if (result == -2) { + PyErr_Format(PyExc_TypeError, + "sign() expected int, long or float, found %s", + Py_Type(arg)->tp_name); + return NULL; + } + return PyInt_FromLong((long)result); +} + +PyDoc_STRVAR(math_sign_doc, +"sign(x) -> +1 / 0 / -1\n\ +Return the sign of an int, long or float. On platforms with full IEE 754\n\ +semantic sign(0.) returns +1 and sign(-0.) returns -1. On other platforms\n\ +sign(0.) always returns 0."); + +#ifdef HAVE_LGAMMA_R +static PyObject * +math_lgamma(PyObject *self, PyObject *arg) +{ + PyObject *result, *o; + double x; + int sign; + + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + errno = 0; + PyFPE_START_PROTECT("in lgamma", return NULL) + x = lgamma_r(x, &sign); + PyFPE_END_PROTECT(x) + Py_SET_ERRNO_ON_MATH_ERROR(x); + if (errno && is_error(x)) + return NULL; + + result = PyTuple_New(2); + if (result == NULL) + return NULL; + o = PyFloat_FromDouble(x); + if (PyTuple_SetItem(result, 0, o) != 0) + return NULL; + o = PyInt_FromLong(sign); + if (PyTuple_SetItem(result, 1, o) != 0) + return NULL; + return result; + +} +PyDoc_STRVAR(math_lgamma_doc, +"lgamma(x) -> (result, sign)\n\ +Return the natural logarithm of the gamma function and the sign of the \n\ +gamma function so that gamma = exp(result) * sign."); +#endif /* HAVE_LGAMMA_R */ + static PyMethodDef math_methods[] = { {"acos", math_acos, METH_O, math_acos_doc}, {"asin", math_asin, METH_O, math_asin_doc}, @@ -314,23 +478,53 @@ {"cos", math_cos, METH_O, math_cos_doc}, {"cosh", math_cosh, METH_O, math_cosh_doc}, {"degrees", math_degrees, METH_O, math_degrees_doc}, +#ifdef HAVE_ERF + {"erf", math_erf, METH_O, math_erf_doc}, +#endif +#ifdef HAVE_ERFC + {"erfc", math_erfc, METH_O, math_erfc_doc}, +#endif {"exp", math_exp, METH_O, math_exp_doc}, {"fabs", math_fabs, METH_O, math_fabs_doc}, {"floor", math_floor, METH_O, math_floor_doc}, {"fmod", math_fmod, METH_VARARGS, math_fmod_doc}, {"frexp", math_frexp, METH_O, math_frexp_doc}, {"hypot", math_hypot, METH_VARARGS, math_hypot_doc}, + {"isinf", math_isinf, METH_O, math_isinf_doc}, + {"isnan", math_isnan, METH_O, math_isnan_doc}, {"ldexp", math_ldexp, METH_VARARGS, math_ldexp_doc}, +#ifdef HAVE_LGAMMA_R + {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, +#endif {"log", math_log, METH_VARARGS, math_log_doc}, {"log10", math_log10, METH_O, math_log10_doc}, {"modf", math_modf, METH_O, math_modf_doc}, {"pow", math_pow, METH_VARARGS, math_pow_doc}, {"radians", math_radians, METH_O, math_radians_doc}, + {"sign", math_sign, METH_O, math_sign_doc}, {"sin", math_sin, METH_O, math_sin_doc}, {"sinh", math_sinh, METH_O, math_sinh_doc}, {"sqrt", math_sqrt, METH_O, math_sqrt_doc}, {"tan", math_tan, METH_O, math_tan_doc}, {"tanh", math_tanh, METH_O, math_tanh_doc}, +#ifdef HAVE_J0 + {"j0", math_j0, METH_O, math_j0_doc}, +#endif +#ifdef HAVE_J1 + {"j1", math_j1, METH_O, math_j1_doc}, +#endif +#ifdef HAVE_JN + {"jn", math_jn, METH_VARARGS, math_jn_doc}, +#endif +#ifdef HAVE_Y0 + {"y0", math_y0, METH_O, math_y0_doc}, +#endif +#ifdef HAVE_Y1 + {"y1", math_y1, METH_O, math_y1_doc}, +#endif +#ifdef HAVE_YN + {"yn", math_yn, METH_VARARGS, math_yn_doc}, +#endif {NULL, NULL} /* sentinel */ }; @@ -351,13 +545,13 @@ if (d == NULL) goto finally; - if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0))) + if (!(v = PyFloat_FromDouble(Py_MATH_PI))) goto finally; if (PyDict_SetItemString(d, "pi", v) < 0) goto finally; Py_DECREF(v); - if (!(v = PyFloat_FromDouble(exp(1.0)))) + if (!(v = PyFloat_FromDouble(Py_MATH_E))) goto finally; if (PyDict_SetItemString(d, "e", v) < 0) goto finally; Index: pyconfig.h.in =================================================================== --- pyconfig.h.in (Revision 59539) +++ pyconfig.h.in (Arbeitskopie) @@ -85,6 +85,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_CONIO_H +/* Define to 1 if you have the `copysign' function. */ +#undef HAVE_COPYSIGN + /* Define to 1 if you have the `ctermid' function. */ #undef HAVE_CTERMID @@ -135,6 +138,12 @@ /* Defined when any dynamic module loading is enabled. */ #undef HAVE_DYNAMIC_LOADING +/* Define to 1 if you have the `erf' function. */ +#undef HAVE_ERF + +/* Define to 1 if you have the `erfc' function. */ +#undef HAVE_ERFC + /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H @@ -288,6 +297,21 @@ /* Define to 1 if you have the header file. */ #undef HAVE_IO_H +/* Define to 1 if you have the `isinf' function. */ +#undef HAVE_ISINF + +/* Define to 1 if you have the `isnan' function. */ +#undef HAVE_ISNAN + +/* Define to 1 if you have the `j0' function. */ +#undef HAVE_J0 + +/* Define to 1 if you have the `j1' function. */ +#undef HAVE_J1 + +/* Define to 1 if you have the `jn' function. */ +#undef HAVE_JN + /* Define to 1 if you have the `kill' function. */ #undef HAVE_KILL @@ -312,6 +336,9 @@ /* Define to 1 if you have the `lchown' function. */ #undef HAVE_LCHOWN +/* Define to 1 if you have the `lgamma_r' function. */ +#undef HAVE_LGAMMA_R + /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL @@ -747,6 +774,15 @@ */ #undef HAVE_WORKING_TZSET +/* Define to 1 if you have the `y0' function. */ +#undef HAVE_Y0 + +/* Define to 1 if you have the `y1' function. */ +#undef HAVE_Y1 + +/* Define to 1 if you have the `yn' function. */ +#undef HAVE_YN + /* Define if the zlib library has inflateCopy */ #undef HAVE_ZLIB_COPY