[pypy-svn] r44976 - in pypy/dist/pypy/rpython/tool: . test
fijal at codespeak.net
fijal at codespeak.net
Thu Jul 12 17:21:51 CEST 2007
Author: fijal
Date: Thu Jul 12 17:21:50 2007
New Revision: 44976
Modified:
pypy/dist/pypy/rpython/tool/mkrffi.py
pypy/dist/pypy/rpython/tool/test/test_c.py
pypy/dist/pypy/rpython/tool/test/test_mkrffi.py
Log:
(simonb, fijal) Make this work for structures as well
Modified: pypy/dist/pypy/rpython/tool/mkrffi.py
==============================================================================
--- pypy/dist/pypy/rpython/tool/mkrffi.py (original)
+++ pypy/dist/pypy/rpython/tool/mkrffi.py Thu Jul 12 17:21:50 2007
@@ -9,20 +9,68 @@
# XXX any automatic stuff here?
SIMPLE_TYPE_MAPPING = {
- ctypes.c_int : 'rffi.INT',
- ctypes.c_voidp : primitive_pointer_repr('lltype.Void')
+ ctypes.c_int : 'rffi.INT',
+ ctypes.c_uint : 'rffi.UINT',
+ ctypes.c_voidp : 'rffi.VOIDP',
}
-def proc_tp(tp):
- try:
- return SIMPLE_TYPE_MAPPING[tp]
- except KeyError:
+class RffiSource(object):
+ def __init__(self, structures=None, code=None):
+ # ctypes structure -> code mapping
+ if structures is None:
+ self.structures = {}
+ else:
+ self.structures = structures
+ # rest of the code
+ if code is None:
+ self.code = py.code.Source()
+ else:
+ self.code = code
+
+ def __add__(self, other):
+ structs = self.structures.copy()
+ structs.update(other.structures)
+ code = py.code.Source(self.code, other.code)
+ return RffiSource(structs, code)
+
+ def __iadd__(self, other):
+ self.structures.update(other.structures)
+ self.code = py.code.Source(self.code, other.code)
+ return self
+
+ def proc_struct(self, tp):
+ name = tp.__name__
+ real_name = 'c_' + name
+ real_name = real_name.rstrip('_structure')
+ real_name += '_structure'
+ if tp not in self.structures:
+ fields = ["('%s', %s)" % (name_, self.proc_tp(field_tp))
+ for name_, field_tp in tp._fields_]
+ fields_repr = ", ".join(fields)
+ self.structures[tp] = py.code.Source(
+ "%s = rffi.CStruct('%s', %s)"%(real_name, name,
+ fields_repr))
+ return real_name
+
+ def proc_tp(self, tp):
+ try:
+ return SIMPLE_TYPE_MAPPING[tp]
+ except KeyError:
+ pass
+ if issubclass(tp, ctypes._Pointer):
+ if issubclass(tp._type_, ctypes._SimpleCData):
+ return "lltype.Ptr(lltype.Array(%s, hints={'nolength': True}))"\
+ % self.proc_tp(tp._type_)
+ return "lltype.Ptr(%s)" % self.proc_tp(tp._type_)
+ elif issubclass(tp, ctypes.Structure):
+ return self.proc_struct(tp)
raise NotImplementedError("Not implemented mapping for %s" % tp)
-def proc_func(func):
- name = func.__name__
- src = py.code.Source("""
- c_%s = rffi.llexternal('%s', [%s], %s)
- """%(name, name, ",".join([proc_tp(arg) for arg in func.argtypes]),
- proc_tp(func.restype)))
- return src
+ def proc_func(self, func):
+ name = func.__name__
+ src = py.code.Source("""
+ c_%s = rffi.llexternal('%s', [%s], %s)
+ """%(name, name, ", ".join([self.proc_tp(arg) for
+ arg in func.argtypes]),
+ self.proc_tp(func.restype)))
+ self.code = py.code.Source(self.code, src)
Modified: pypy/dist/pypy/rpython/tool/test/test_c.py
==============================================================================
--- pypy/dist/pypy/rpython/tool/test/test_c.py (original)
+++ pypy/dist/pypy/rpython/tool/test/test_c.py Thu Jul 12 17:21:50 2007
@@ -8,6 +8,13 @@
c_source = """
void *int_to_void_p(int arg) {}
+
+struct random_strucutre {
+ int one;
+ int *two;
+};
+
+struct random_structure* int_int_to_struct_p(int one, int two) {}
"""
class TestBasic:
Modified: pypy/dist/pypy/rpython/tool/test/test_mkrffi.py
==============================================================================
--- pypy/dist/pypy/rpython/tool/test/test_mkrffi.py (original)
+++ pypy/dist/pypy/rpython/tool/test/test_mkrffi.py Thu Jul 12 17:21:50 2007
@@ -4,15 +4,56 @@
from pypy.rpython.tool.test.test_c import TestBasic
import py
+class random_structure(ctypes.Structure):
+ _fields_ = [('one', ctypes.c_int),
+ ('two', ctypes.POINTER(ctypes.c_int))]
+
+def test_rffisource():
+ res = RffiSource({1:2, 3:4}, "ab") + RffiSource(None, "c")
+ assert res.structures == {1:2, 3:4}
+ assert str(res.code) == "ab\nc"
+ res += RffiSource({5:6})
+ assert 5 in res.structures.keys()
+
+def test_proc_tp_simple():
+ rffi_source = RffiSource()
+ assert rffi_source.proc_tp(ctypes.c_int) == 'rffi.INT'
+ assert rffi_source.proc_tp(ctypes.c_void_p) == 'rffi.VOIDP'
+
+def test_proc_tp_complicated():
+ rffi_source = RffiSource()
+ assert rffi_source.proc_tp(ctypes.POINTER(ctypes.c_uint)) == \
+ "lltype.Ptr(lltype.Array(rffi.UINT, hints={'nolength': True}))"
+ rffi_source.proc_tp(random_structure)
+ _src = py.code.Source("""
+ c_random_structure = rffi.CStruct('random_structure', ('one', rffi.INT), ('two', lltype.Ptr(lltype.Array(rffi.INT, hints={'nolength': True}))))
+ """)
+ src = rffi_source.structures[random_structure]
+ assert src.strip() == _src.strip(), str(src) + "\n" + str(_src)
+
class TestMkrffi(TestBasic):
def test_single_func(self):
func = self.lib.int_to_void_p
func.argtypes = [ctypes.c_int]
func.restype = ctypes.c_voidp
- src = proc_func(func)
+ src = RffiSource()
+ src.proc_func(func)
_src = py.code.Source("""
- c_int_to_void_p = rffi.llexternal('int_to_void_p', [rffi.INT], lltype.Ptr(lltype.FixedSizeArray(lltype.Void, 1)))
+ c_int_to_void_p = rffi.llexternal('int_to_void_p', [rffi.INT], rffi.VOIDP)
""")
- assert src == _src, str(src) + "\n" + str(_src)
+ assert src.code == _src, str(src) + "\n" + str(_src)
+
+ def test_struct_return(self):
+ func = self.lib.int_int_to_struct_p
+ func.argtypes = [ctypes.c_int, ctypes.c_int]
+ func.restype = ctypes.POINTER(random_structure)
+ rffi_source = RffiSource()
+ rffi_source.proc_func(func)
+ assert random_structure in rffi_source.structures
+ _src = py.code.Source("""
+ c_int_int_to_struct_p = rffi.llexternal('int_int_to_struct_p', [rffi.INT, rffi.INT], lltype.Ptr(c_random_structure))
+ """)
+ src = rffi_source.code
+ assert src.strip() == _src.strip(), str(src) + "\n" + str(_src)
More information about the Pypy-commit
mailing list