[pypy-commit] pypy rffi-parser-2: Configure types using only the C source passed to parse_source()
rlamy
pypy.commits at gmail.com
Fri Jan 13 11:13:52 EST 2017
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: rffi-parser-2
Changeset: r89544:bdd3e262b996
Date: 2017-01-13 16:13 +0000
http://bitbucket.org/pypy/pypy/changeset/bdd3e262b996/
Log: Configure types using only the C source passed to parse_source()
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
@@ -974,7 +974,7 @@
} PyTypeObject;
-""", configure_now=True)
+""", headers=['sys/types.h', 'stdarg.h', 'stdio.h'], configure_now=True)
Py_ssize_t = object_h.gettype('Py_ssize_t')
Py_ssize_tP = object_h.gettype('Py_ssize_t *')
diff --git a/pypy/module/cpyext/cparser.py b/pypy/module/cpyext/cparser.py
--- a/pypy/module/cpyext/cparser.py
+++ b/pypy/module/cpyext/cparser.py
@@ -6,6 +6,7 @@
except ImportError:
import pycparser
import weakref, re
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
from rpython.rlib.rfile import FILEP
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rtyper.tool import rfficache, rffi_platform
@@ -675,17 +676,15 @@
class ParsedSource(object):
- def __init__(self, source, parser, definitions=None, macros=None, eci=None):
+ def __init__(self, source, parser, definitions=None, macros=None, headers=None):
from pypy.module.cpyext.api import configure_eci
self.source = source
self.definitions = definitions if definitions is not None else {}
self.macros = macros if macros is not None else {}
self.structs = {}
self.ctx = parser
- if eci is None:
- eci = configure_eci
- self._Config = type(
- 'Config', (object,), {'_compilation_info_': eci})
+ self.headers = headers if headers is not None else ['sys/types.h']
+ self._Config = type('Config', (object,), {})
self._TYPES = {}
self.includes = []
@@ -728,6 +727,16 @@
cpython_struct(type_name, struct.fields, forward=struct.TYPE)
return struct.TYPE
+ def build_eci(self):
+ all_sources = [x.source for x in self.includes] + [self.source]
+ all_headers = self.headers
+ for x in self.includes:
+ for hdr in x.headers:
+ if hdr not in all_headers:
+ all_headers.append(hdr)
+ return ExternalCompilationInfo(
+ post_include_bits=all_sources, includes=all_headers)
+
def configure_types(self, configure_now=False):
for name, (obj, quals) in self.ctx._declarations.iteritems():
if obj in self.ctx._included_declarations:
@@ -738,6 +747,7 @@
elif name.startswith('macro '):
name = name[6:]
self.add_macro(name, obj)
+ self._Config._compilation_info_ = self.build_eci()
for name, TYPE in rffi_platform.configure(self._Config).iteritems():
if name in self._TYPES:
self._TYPES[name].become(TYPE)
@@ -794,9 +804,9 @@
return decl.name, FUNCP.TO
-def parse_source(source, includes=None, eci=None, configure_now=False):
+def parse_source(source, includes=None, headers=None, configure_now=False):
ctx = Parser()
- src = ParsedSource(source, ctx, eci=eci)
+ src = ParsedSource(source, ctx, headers=headers)
if includes is not None:
for header in includes:
src.include(header)
diff --git a/pypy/module/cpyext/test/test_cparser.py b/pypy/module/cpyext/test/test_cparser.py
--- a/pypy/module/cpyext/test/test_cparser.py
+++ b/pypy/module/cpyext/test/test_cparser.py
@@ -1,8 +1,7 @@
from rpython.rtyper.lltypesystem import rffi, lltype
-from rpython.translator.tool.cbuild import ExternalCompilationInfo
from pypy.module.cpyext.cparser import parse_source
-def test_configure(tmpdir):
+def test_configure():
decl = """
typedef ssize_t Py_ssize_t;
@@ -12,11 +11,7 @@
double ob_fval;
} TestFloatObject;
"""
- hdr = tmpdir / 'header.h'
- hdr.write(decl)
- eci = ExternalCompilationInfo(
- include_dirs=[str(tmpdir)], includes=['sys/types.h', 'header.h'])
- res = parse_source(decl, eci=eci, configure_now=True)
+ res = parse_source(decl, configure_now=True)
TestFloatObject = res.definitions['TestFloatObject']
assert isinstance(TestFloatObject, lltype.Struct)
assert TestFloatObject.c_ob_refcnt == rffi.SSIZE_T
@@ -45,7 +40,7 @@
assert 'PyFloatObject' in hdr.definitions
assert 'PyObject_HEAD' in hdr.macros
-def test_include(tmpdir):
+def test_include():
cdef1 = """
typedef ssize_t Py_ssize_t;
@@ -57,8 +52,6 @@
char *name;
} Type;
"""
- base_name = tmpdir / 'base.h'
- base_name.write(cdef1)
cdef2 = """
typedef struct {
PyObject_HEAD
@@ -66,19 +59,15 @@
Type *type;
} Object;
"""
- (tmpdir / 'object.h').write(cdef2)
- eci = ExternalCompilationInfo(
- include_dirs=[str(tmpdir)],
- includes=['sys/types.h', 'base.h', 'object.h'])
- hdr1 = parse_source(cdef1, eci=eci, configure_now=True)
+ hdr1 = parse_source(cdef1, configure_now=True)
Type = hdr1.definitions['Type']
assert isinstance(Type, lltype.Struct)
- hdr2 = parse_source(cdef2, includes=[hdr1], eci=eci, configure_now=True)
+ hdr2 = parse_source(cdef2, includes=[hdr1], configure_now=True)
assert 'Type' not in hdr2.definitions
Object = hdr2.definitions['Object']
assert Object.c_type.TO is Type
-def test_incomplete(tmpdir):
+def test_incomplete():
cdef = """
typedef ssize_t Py_ssize_t;
@@ -94,15 +83,11 @@
} Buffer;
"""
- (tmpdir / 'foo.h').write(cdef)
- eci = ExternalCompilationInfo(
- include_dirs=[str(tmpdir)],
- includes=['sys/types.h', 'foo.h'])
- foo_h = parse_source(cdef, eci=eci)
+ foo_h = parse_source(cdef)
Object = foo_h.gettype('Object')
assert isinstance(Object, lltype.ForwardReference)
-def test_recursive(tmpdir):
+def test_recursive():
cdef = """
typedef ssize_t Py_ssize_t;
@@ -121,29 +106,21 @@
Object *obj;
} Type;
"""
- (tmpdir / 'foo.h').write(cdef)
- eci = ExternalCompilationInfo(
- include_dirs=[str(tmpdir)],
- includes=['sys/types.h', 'foo.h'])
- foo_h = parse_source(cdef, eci=eci, configure_now=True)
+ foo_h = parse_source(cdef, configure_now=True)
Object = foo_h.definitions['Object']
assert isinstance(Object, lltype.Struct)
hash(Object)
-def test_const(tmpdir):
+def test_const():
cdef = """
typedef struct {
const char * const foo;
} bar;
"""
- (tmpdir / 'foo.h').write(cdef)
- eci = ExternalCompilationInfo(
- include_dirs=[str(tmpdir)],
- includes=['sys/types.h', 'foo.h'])
- hdr = parse_source(cdef, eci=eci, configure_now=True)
+ hdr = parse_source(cdef, configure_now=True)
assert hdr.definitions['bar'].c_foo == rffi.CONST_CCHARP != rffi.CCHARP
-def test_gettype(tmpdir):
+def test_gettype():
decl = """
typedef ssize_t Py_ssize_t;
@@ -156,15 +133,11 @@
double ob_fval;
} TestFloatObject;
"""
- hdr = tmpdir / 'header.h'
- hdr.write(decl)
- eci = ExternalCompilationInfo(
- include_dirs=[str(tmpdir)], includes=['sys/types.h', 'header.h'])
- res = parse_source(decl, eci=eci, configure_now=True)
+ res = parse_source(decl, configure_now=True)
assert res.gettype('Py_ssize_t') == rffi.SSIZE_T
assert res.gettype('TestFloatObject *').TO.c_ob_refcnt == rffi.SSIZE_T
-def test_parse_funcdecl(tmpdir):
+def test_parse_funcdecl():
decl = """
typedef ssize_t Py_ssize_t;
@@ -179,11 +152,7 @@
typedef TestFloatObject* (*func_t)(int, int);
"""
- hdr = tmpdir / 'header.h'
- hdr.write(decl)
- eci = ExternalCompilationInfo(
- include_dirs=[str(tmpdir)], includes=['sys/types.h', 'header.h'])
- res = parse_source(decl, eci=eci, configure_now=True)
+ res = parse_source(decl, configure_now=True)
name, FUNC = res.parse_func("func_t some_func(TestFloatObject*)")
assert name == 'some_func'
assert FUNC.RESULT == res.gettype('func_t')
More information about the pypy-commit
mailing list