[Python-checkins] r58034 - in python/trunk: Doc/library/ctypes.rst Lib/ctypes/__init__.py Lib/ctypes/test/test_arrays.py Lib/ctypes/test/test_callbacks.py Lib/ctypes/test/test_cfuncs.py Lib/ctypes/test/test_functions.py Lib/ctypes/test/test_repr.py Misc/NEWS Modules/_ctypes/_ctypes.c Modules/_ctypes/_ctypes_test.c Modules/_ctypes/callproc.c Modules/_ctypes/cfield.c Modules/_ctypes/ctypes.h

thomas.heller python-checkins at python.org
Fri Sep 7 08:32:17 CEST 2007


Author: thomas.heller
Date: Fri Sep  7 08:32:17 2007
New Revision: 58034

Modified:
   python/trunk/Doc/library/ctypes.rst
   python/trunk/Lib/ctypes/__init__.py
   python/trunk/Lib/ctypes/test/test_arrays.py
   python/trunk/Lib/ctypes/test/test_callbacks.py
   python/trunk/Lib/ctypes/test/test_cfuncs.py
   python/trunk/Lib/ctypes/test/test_functions.py
   python/trunk/Lib/ctypes/test/test_repr.py
   python/trunk/Misc/NEWS
   python/trunk/Modules/_ctypes/_ctypes.c
   python/trunk/Modules/_ctypes/_ctypes_test.c
   python/trunk/Modules/_ctypes/callproc.c
   python/trunk/Modules/_ctypes/cfield.c
   python/trunk/Modules/_ctypes/ctypes.h
Log:
Add a 'c_longdouble' type to the ctypes module.

Modified: python/trunk/Doc/library/ctypes.rst
==============================================================================
--- python/trunk/Doc/library/ctypes.rst	(original)
+++ python/trunk/Doc/library/ctypes.rst	Fri Sep  7 08:32:17 2007
@@ -249,6 +249,8 @@
    +----------------------+--------------------------------+----------------------------+
    | :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 @@
    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

Modified: python/trunk/Lib/ctypes/__init__.py
==============================================================================
--- python/trunk/Lib/ctypes/__init__.py	(original)
+++ python/trunk/Lib/ctypes/__init__.py	Fri Sep  7 08:32:17 2007
@@ -191,6 +191,11 @@
     _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

Modified: python/trunk/Lib/ctypes/test/test_arrays.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_arrays.py	(original)
+++ python/trunk/Lib/ctypes/test/test_arrays.py	Fri Sep  7 08:32:17 2007
@@ -4,7 +4,7 @@
 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):

Modified: python/trunk/Lib/ctypes/test/test_callbacks.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_callbacks.py	(original)
+++ python/trunk/Lib/ctypes/test/test_callbacks.py	Fri Sep  7 08:32:17 2007
@@ -77,6 +77,10 @@
         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")

Modified: python/trunk/Lib/ctypes/test/test_cfuncs.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_cfuncs.py	(original)
+++ python/trunk/Lib/ctypes/test/test_cfuncs.py	Fri Sep  7 08:32:17 2007
@@ -158,6 +158,18 @@
         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

Modified: python/trunk/Lib/ctypes/test/test_functions.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_functions.py	(original)
+++ python/trunk/Lib/ctypes/test/test_functions.py	Fri Sep  7 08:32:17 2007
@@ -143,6 +143,18 @@
         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

Modified: python/trunk/Lib/ctypes/test/test_repr.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_repr.py	(original)
+++ python/trunk/Lib/ctypes/test/test_repr.py	Fri Sep  7 08:32:17 2007
@@ -4,7 +4,7 @@
 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)

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Fri Sep  7 08:32:17 2007
@@ -249,6 +249,8 @@
 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

Modified: python/trunk/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/trunk/Modules/_ctypes/_ctypes.c	(original)
+++ python/trunk/Modules/_ctypes/_ctypes.c	Fri Sep  7 08:32:17 2007
@@ -1101,7 +1101,7 @@
 
 */
 
-static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOvt";
+static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOvtD";
 
 static PyObject *
 c_wchar_p_from_param(PyObject *type, PyObject *value)

Modified: python/trunk/Modules/_ctypes/_ctypes_test.c
==============================================================================
--- python/trunk/Modules/_ctypes/_ctypes_test.c	(original)
+++ python/trunk/Modules/_ctypes/_ctypes_test.c	Fri Sep  7 08:32:17 2007
@@ -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 @@
 	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(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(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(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(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
 

Modified: python/trunk/Modules/_ctypes/callproc.c
==============================================================================
--- python/trunk/Modules/_ctypes/callproc.c	(original)
+++ python/trunk/Modules/_ctypes/callproc.c	Fri Sep  7 08:32:17 2007
@@ -449,6 +449,7 @@
 #ifdef HAVE_LONG_LONG
 	PY_LONG_LONG q;
 #endif
+	long double D;
 	double d;
 	float f;
 	void *p;

Modified: python/trunk/Modules/_ctypes/cfield.c
==============================================================================
--- python/trunk/Modules/_ctypes/cfield.c	(original)
+++ python/trunk/Modules/_ctypes/cfield.c	Fri Sep  7 08:32:17 2007
@@ -5,6 +5,7 @@
 #include "Python.h"
 
 #include <ffi.h>
+#include <fficonfig.h>
 #ifdef MS_WIN32
 #include <windows.h>
 #endif
@@ -989,6 +990,29 @@
  */
 
 
+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 @@
 	{ '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; 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 @@
 */
 #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_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 */
 

Modified: python/trunk/Modules/_ctypes/ctypes.h
==============================================================================
--- python/trunk/Modules/_ctypes/ctypes.h	(original)
+++ python/trunk/Modules/_ctypes/ctypes.h	Fri Sep  7 08:32:17 2007
@@ -47,6 +47,7 @@
 #ifdef HAVE_LONG_LONG
 		PY_LONG_LONG ll;
 #endif
+		long double D;
 };
 
 /*
@@ -300,6 +301,7 @@
 #ifdef HAVE_LONG_LONG
 		PY_LONG_LONG q;
 #endif
+		long double D;
 		double d;
 		float f;
 		void *p;


More information about the Python-checkins mailing list