Author: Ronan Lamy <[email protected]>
Branch: api_func-refactor
Changeset: r89432:deeb13497468
Date: 2017-01-09 01:12 +0000
http://bitbucket.org/pypy/pypy/changeset/deeb13497468/

Log:    Move C code generation code to methods of ApiFunction

diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -329,6 +329,47 @@
             wrapper.c_name = cpyext_namespace.uniquename(self.c_name)
         return wrapper
 
+    def get_c_restype(self, c_writer):
+        return c_writer.gettype(self.restype).replace('@', '').strip()
+
+    def get_c_args(self, c_writer):
+        args = []
+        for i, argtype in enumerate(self.argtypes):
+            if argtype is CONST_STRING:
+                arg = 'const char *@'
+            elif argtype is CONST_STRINGP:
+                arg = 'const char **@'
+            elif argtype is CONST_WSTRING:
+                arg = 'const wchar_t *@'
+            else:
+                arg = c_writer.gettype(argtype)
+            arg = arg.replace('@', 'arg%d' % (i,)).strip()
+            args.append(arg)
+        args = ', '.join(args) or "void"
+        return args
+
+    def get_api_decl(self, name, c_writer):
+        restype = self.get_c_restype(c_writer)
+        args = self.get_c_args(c_writer)
+        return "PyAPI_FUNC({restype}) {name}({args});".format(**locals())
+
+    def get_ptr_decl(self, name, c_writer):
+        restype = self.get_c_restype(c_writer)
+        args = self.get_c_args(c_writer)
+        return "{restype} (*{name})({args});".format(**locals())
+
+    def get_ctypes_impl(self, name, c_writer):
+        restype = self.get_c_restype(c_writer)
+        args = self.get_c_args(c_writer)
+        callargs = ', '.join('arg%d' % (i,)
+                            for i in range(len(self.argtypes)))
+        if self.restype is lltype.Void:
+            body = "{ _pypyAPI.%s(%s); }" % (name, callargs)
+        else:
+            body = "{ return _pypyAPI.%s(%s); }" % (name, callargs)
+        return '%s %s(%s)\n%s' % (restype, name, args, body)
+
+
 DEFAULT_HEADER = 'pypy_decl.h'
 def cpython_api(argtypes, restype, error=_NOT_SPECIFIED, header=DEFAULT_HEADER,
                 gil=None, result_borrowed=False, result_is_ll=False):
@@ -987,23 +1028,6 @@
     for func in BOOTSTRAP_FUNCTIONS:
         func(space)
 
-def c_function_signature(db, func):
-    restype = db.gettype(func.restype).replace('@', '').strip()
-    args = []
-    for i, argtype in enumerate(func.argtypes):
-        if argtype is CONST_STRING:
-            arg = 'const char *@'
-        elif argtype is CONST_STRINGP:
-            arg = 'const char **@'
-        elif argtype is CONST_WSTRING:
-            arg = 'const wchar_t *@'
-        else:
-            arg = db.gettype(argtype)
-        arg = arg.replace('@', 'arg%d' % (i,)).strip()
-        args.append(arg)
-    args = ', '.join(args) or "void"
-    return restype, args
-
 #_____________________________________________________
 # Build the bridge DLL, Allow extension DLLs to call
 # back into Pypy space functions
@@ -1023,15 +1047,8 @@
     structindex = {}
     for header, header_functions in FUNCTIONS_BY_HEADER.iteritems():
         for name, func in header_functions.iteritems():
-            restype, args = c_function_signature(db, func)
-            callargs = ', '.join('arg%d' % (i,)
-                                for i in range(len(func.argtypes)))
-            if func.restype is lltype.Void:
-                body = "{ _pypyAPI.%s(%s); }" % (name, callargs)
-            else:
-                body = "{ return _pypyAPI.%s(%s); }" % (name, callargs)
-            functions.append('%s %s(%s)\n%s' % (restype, name, args, body))
-            members.append('%s (*%s)(%s);' % (restype, name, args))
+            functions.append(func.get_ctypes_impl(name, db))
+            members.append(func.get_ptr_decl(name, db))
             structindex[name] = len(structindex)
     structmembers = '\n'.join(members)
     struct_declaration_code = """\
@@ -1226,8 +1243,7 @@
         for name, func in sorted(header_functions.iteritems()):
             _name = mangle_name(prefix, name)
             header.append("#define %s %s" % (name, _name))
-            restype, args = c_function_signature(db, func)
-            header.append("PyAPI_FUNC(%s) %s(%s);" % (restype, name, args))
+            header.append(func.get_api_decl(name, db))
 
     for name, (typ, expr) in GLOBALS.iteritems():
         if '#' in name:
diff --git a/pypy/module/cpyext/test/test_api.py 
b/pypy/module/cpyext/test/test_api.py
--- a/pypy/module/cpyext/test/test_api.py
+++ b/pypy/module/cpyext/test/test_api.py
@@ -89,10 +89,10 @@
     def test_typedef(self, space):
         from rpython.translator.c.database import LowLevelDatabase
         db = LowLevelDatabase()
-        assert (api.c_function_signature(db, PyPy_TypedefTest1.api_func)
-                == ('Py_ssize_t', 'Py_ssize_t arg0'))
-        assert (api.c_function_signature(db, PyPy_TypedefTest2.api_func)
-                == ('Py_ssize_t *', 'Py_ssize_t *arg0'))
+        assert PyPy_TypedefTest1.api_func.get_c_restype(db) == 'Py_ssize_t'
+        assert PyPy_TypedefTest1.api_func.get_c_args(db) == 'Py_ssize_t arg0'
+        assert PyPy_TypedefTest2.api_func.get_c_restype(db) == 'Py_ssize_t *'
+        assert PyPy_TypedefTest2.api_func.get_c_args(db) == 'Py_ssize_t *arg0'
 
         PyPy_TypedefTest1(space, 0)
         ppos = lltype.malloc(api.Py_ssize_tP.TO, 1, flavor='raw')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to