diff options
author | Thomas Heller <theller@ctypes.org> | 2007-09-07 06:32:17 (GMT) |
---|---|---|
committer | Thomas Heller <theller@ctypes.org> | 2007-09-07 06:32:17 (GMT) |
commit | 2825b2ea444e3ce03cac7fc562fe6b7166972459 (patch) | |
tree | 418a77753ce23a6520adec24ed4294f51ed786d5 | |
parent | 1e534b5425d836cb58a73d24f0be791d67bf3503 (diff) | |
download | cpython-2825b2ea444e3ce03cac7fc562fe6b7166972459.zip cpython-2825b2ea444e3ce03cac7fc562fe6b7166972459.tar.gz cpython-2825b2ea444e3ce03cac7fc562fe6b7166972459.tar.bz2 |
Add a 'c_longdouble' type to the ctypes module.
-rw-r--r-- | Doc/library/ctypes.rst | 9 | ||||
-rw-r--r-- | Lib/ctypes/__init__.py | 5 | ||||
-rw-r--r-- | Lib/ctypes/test/test_arrays.py | 2 | ||||
-rw-r--r-- | Lib/ctypes/test/test_callbacks.py | 4 | ||||
-rw-r--r-- | Lib/ctypes/test/test_cfuncs.py | 12 | ||||
-rw-r--r-- | Lib/ctypes/test/test_functions.py | 12 | ||||
-rw-r--r-- | Lib/ctypes/test/test_repr.py | 2 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Modules/_ctypes/_ctypes.c | 2 | ||||
-rw-r--r-- | Modules/_ctypes/_ctypes_test.c | 35 | ||||
-rw-r--r-- | Modules/_ctypes/callproc.c | 1 | ||||
-rw-r--r-- | Modules/_ctypes/cfield.c | 30 | ||||
-rw-r--r-- | Modules/_ctypes/ctypes.h | 2 |
13 files changed, 115 insertions, 3 deletions
diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 6c9dbf8..a5d4a48 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -249,6 +249,8 @@ Fundamental data types +----------------------+--------------------------------+----------------------------+ | :class:`c_double` | ``double`` | float | +----------------------+--------------------------------+----------------------------+ + | :class:`c_longdouble`| ``long double`` | float | + +----------------------+--------------------------------+----------------------------+ | :class:`c_char_p` | ``char *`` (NUL terminated) | string or ``None`` | +----------------------+--------------------------------+----------------------------+ | :class:`c_wchar_p` | ``wchar_t *`` (NUL terminated) | unicode or ``None`` | @@ -2067,6 +2069,13 @@ These are the fundamental ctypes data types: initializer. +.. class:: c_longdouble + + Represents the C long double datatype. The constructor accepts an + optional float initializer. On platforms where ``sizeof(long + double) == sizeof(double)`` it is an alias to :class:`c_double`. + + .. class:: c_float Represents the C float datatype. The constructor accepts an optional float diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 8ab84ac..3ad3161 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -191,6 +191,11 @@ class c_double(_SimpleCData): _type_ = "d" _check_size(c_double) +class c_longdouble(_SimpleCData): + _type_ = "D" +if sizeof(c_longdouble) == sizeof(c_double): + c_longdouble = c_double + if _calcsize("l") == _calcsize("q"): # if long and long long have the same size, make c_longlong an alias for c_long c_longlong = c_long diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/ctypes/test/test_arrays.py index a68ef61..e635ae1 100644 --- a/Lib/ctypes/test/test_arrays.py +++ b/Lib/ctypes/test/test_arrays.py @@ -4,7 +4,7 @@ from ctypes import * formats = "bBhHiIlLqQfd" formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \ - c_long, c_ulonglong, c_float, c_double + c_long, c_ulonglong, c_float, c_double, c_longdouble class ArrayTestCase(unittest.TestCase): def test_simple(self): diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py index f47fc37..e3e4be8 100644 --- a/Lib/ctypes/test/test_callbacks.py +++ b/Lib/ctypes/test/test_callbacks.py @@ -77,6 +77,10 @@ class Callbacks(unittest.TestCase): self.check_type(c_double, 3.14) self.check_type(c_double, -3.14) + def test_longdouble(self): + self.check_type(c_longdouble, 3.14) + self.check_type(c_longdouble, -3.14) + def test_char(self): self.check_type(c_char, "x") self.check_type(c_char, "a") diff --git a/Lib/ctypes/test/test_cfuncs.py b/Lib/ctypes/test/test_cfuncs.py index fa858a6..7241006 100644 --- a/Lib/ctypes/test/test_cfuncs.py +++ b/Lib/ctypes/test/test_cfuncs.py @@ -158,6 +158,18 @@ class CFunctions(unittest.TestCase): self.failUnlessEqual(self._dll.tf_bd(0, 42.), 14.) self.failUnlessEqual(self.S(), 42) + def test_longdouble(self): + self._dll.tf_D.restype = c_longdouble + self._dll.tf_D.argtypes = (c_longdouble,) + self.failUnlessEqual(self._dll.tf_D(42.), 14.) + self.failUnlessEqual(self.S(), 42) + + def test_longdouble_plus(self): + self._dll.tf_bD.restype = c_longdouble + self._dll.tf_bD.argtypes = (c_byte, c_longdouble) + self.failUnlessEqual(self._dll.tf_bD(0, 42.), 14.) + self.failUnlessEqual(self.S(), 42) + def test_callwithresult(self): def process_result(result): return result * 2 diff --git a/Lib/ctypes/test/test_functions.py b/Lib/ctypes/test/test_functions.py index 12bd59c..93d895b 100644 --- a/Lib/ctypes/test/test_functions.py +++ b/Lib/ctypes/test/test_functions.py @@ -143,6 +143,18 @@ class FunctionTestCase(unittest.TestCase): self.failUnlessEqual(result, -21) self.failUnlessEqual(type(result), float) + def test_longdoubleresult(self): + f = dll._testfunc_D_bhilfD + f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_longdouble] + f.restype = c_longdouble + result = f(1, 2, 3, 4, 5.0, 6.0) + self.failUnlessEqual(result, 21) + self.failUnlessEqual(type(result), float) + + result = f(-1, -2, -3, -4, -5.0, -6.0) + self.failUnlessEqual(result, -21) + self.failUnlessEqual(type(result), float) + def test_longlongresult(self): try: c_longlong diff --git a/Lib/ctypes/test/test_repr.py b/Lib/ctypes/test/test_repr.py index f6f9366..9fef21f 100644 --- a/Lib/ctypes/test/test_repr.py +++ b/Lib/ctypes/test/test_repr.py @@ -4,7 +4,7 @@ import unittest subclasses = [] for base in [c_byte, c_short, c_int, c_long, c_longlong, c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong, - c_float, c_double, c_bool]: + c_float, c_double, c_longdouble, c_bool]: class X(base): pass subclasses.append(X) @@ -249,6 +249,8 @@ Core and builtins Library ------- +- A 'c_longdouble' type was added to the ctypes module. + - Bug #1709599: Run test_1565150 only if the file system is NTFS. - When encountering a password-protected robots.txt file the RobotFileParser diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 4c7c896..3b2c72a 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1101,7 +1101,7 @@ _type_ attribute. */ -static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOvt"; +static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOvtD"; static PyObject * c_wchar_p_from_param(PyObject *type, PyObject *value) diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 5cedd19..0d47740 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -25,6 +25,29 @@ /* some functions handy for testing */ +EXPORT(long double)testfunc_Ddd(double a, double b) +{ + long double result = (long double)(a * b); + printf("testfunc_Ddd(%p, %p)\n", &a, &b); + printf("testfunc_Ddd(%g, %g)\n", a, b); + return result; +} + +EXPORT(long double)testfunc_DDD(long double a, long double b) +{ + long double result = a * b; + printf("testfunc_DDD(%p, %p)\n", &a, &b); + printf("testfunc_DDD(%Lg, %Lg)\n", a, b); + return result; +} + +EXPORT(int)testfunc_iii(int a, int b) +{ + int result = a * b; + printf("testfunc_iii(%p, %p)\n", &a, &b); + return result; +} + EXPORT(int)myprintf(char *fmt, ...) { int result; @@ -90,6 +113,14 @@ EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f return (double)(b + h + i + l + f + d); } +EXPORT(long double) _testfunc_D_bhilfD(signed char b, short h, int i, long l, float f, long double d) +{ +/* printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n", + b, h, i, l, f, d); +*/ + return (long double)(b + h + i + l + f + d); +} + EXPORT(char *) _testfunc_p_p(void *s) { return (char *)s; @@ -404,6 +435,7 @@ EXPORT(PY_LONG_LONG) tf_q(PY_LONG_LONG c) { S; return c/3; } EXPORT(unsigned PY_LONG_LONG) tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; } EXPORT(float) tf_f(float c) { S; return c/3; } EXPORT(double) tf_d(double c) { S; return c/3; } +EXPORT(long double) tf_D(long double c) { S; return c/3; } #ifdef MS_WIN32 EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; } @@ -418,6 +450,7 @@ EXPORT(PY_LONG_LONG) __stdcall s_tf_q(PY_LONG_LONG c) { S; return c/3; } EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_Q(unsigned PY_LONG_LONG c) { U; return c/3; } EXPORT(float) __stdcall s_tf_f(float c) { S; return c/3; } EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; } +EXPORT(long double) __stdcall s_tf_D(long double c) { S; return c/3; } #endif /*******/ @@ -433,6 +466,7 @@ EXPORT(PY_LONG_LONG) tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; } EXPORT(unsigned PY_LONG_LONG) tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; } EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; } EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; } +EXPORT(long double) tf_bD(signed char x, long double c) { S; return c/3; } EXPORT(void) tv_i(int c) { S; return; } #ifdef MS_WIN32 @@ -448,6 +482,7 @@ EXPORT(PY_LONG_LONG) __stdcall s_tf_bq(signed char x, PY_LONG_LONG c) { S; retur EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; } EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; } EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; } +EXPORT(long double) __stdcall s_tf_bD(signed char x, long double c) { S; return c/3; } EXPORT(void) __stdcall s_tv_i(int c) { S; return; } #endif diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 80d6dff..7a69e21 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -449,6 +449,7 @@ union result { #ifdef HAVE_LONG_LONG PY_LONG_LONG q; #endif + long double D; double d; float f; void *p; diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 0e4c19e..872a6ee 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -5,6 +5,7 @@ #include "Python.h" #include <ffi.h> +#include <fficonfig.h> #ifdef MS_WIN32 #include <windows.h> #endif @@ -989,6 +990,29 @@ Q_get_sw(void *ptr, Py_ssize_t size) */ +static PyObject * +D_set(void *ptr, PyObject *value, Py_ssize_t size) +{ + long double x; + + x = PyFloat_AsDouble(value); + if (x == -1 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, + " float expected instead of %s instance", + value->ob_type->tp_name); + return NULL; + } + memcpy(ptr, &x, sizeof(long double)); + _RET(value); +} + +static PyObject * +D_get(void *ptr, Py_ssize_t size) +{ + long double val; + memcpy(&val, ptr, sizeof(long double)); + return PyFloat_FromDouble(val); +} static PyObject * d_set(void *ptr, PyObject *value, Py_ssize_t size) @@ -1584,6 +1608,7 @@ static struct fielddesc formattable[] = { { 'B', B_set, B_get, &ffi_type_uchar}, { 'c', c_set, c_get, &ffi_type_schar}, { 'd', d_set, d_get, &ffi_type_double, d_set_sw, d_get_sw}, + { 'D', D_set, D_get, &ffi_type_longdouble}, { 'f', f_set, f_get, &ffi_type_float, f_set_sw, f_get_sw}, { 'h', h_set, h_get, &ffi_type_sshort, h_set_sw, h_get_sw}, { 'H', H_set, H_get, &ffi_type_ushort, H_set_sw, H_get_sw}, @@ -1666,6 +1691,7 @@ typedef struct { char c; int x; } s_int; typedef struct { char c; long x; } s_long; typedef struct { char c; float x; } s_float; typedef struct { char c; double x; } s_double; +typedef struct { char c; long double x; } s_long_double; typedef struct { char c; char *x; } s_char_p; typedef struct { char c; void *x; } s_void_p; @@ -1677,6 +1703,8 @@ typedef struct { char c; void *x; } s_void_p; */ #define FLOAT_ALIGN (sizeof(s_float) - sizeof(float)) #define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double)) +#define LONGDOUBLE_ALIGN (sizeof(s_long_double) - sizeof(long double)) + /* #define CHAR_P_ALIGN (sizeof(s_char_p) - sizeof(char*)) */ #define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*)) @@ -1722,6 +1750,8 @@ ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 }; ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT }; ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE }; +ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN, + FFI_TYPE_LONGDOUBLE }; /* ffi_type ffi_type_longdouble */ diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index bf2bdaa..b6f2382 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -47,6 +47,7 @@ union value { #ifdef HAVE_LONG_LONG PY_LONG_LONG ll; #endif + long double D; }; /* @@ -300,6 +301,7 @@ struct tagPyCArgObject { #ifdef HAVE_LONG_LONG PY_LONG_LONG q; #endif + long double D; double d; float f; void *p; |