[pypy-commit] pypy rffi-parser: Deal with parameterless macros
rlamy
pypy.commits at gmail.com
Fri Dec 16 11:31:57 EST 2016
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: rffi-parser
Changeset: r89102:11a2deff4a3d
Date: 2016-12-16 16:31 +0000
http://bitbucket.org/pypy/pypy/changeset/11a2deff4a3d/
Log: Deal with parameterless macros
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
@@ -45,6 +45,10 @@
csource = _r_stdcall2.sub(' volatile volatile const(', csource)
csource = _r_stdcall1.sub(' volatile volatile const ', csource)
csource = _r_cdecl.sub(' ', csource)
+
+ for name, value in reversed(macros.items()):
+ csource = re.sub(r'\b%s\b' % name, value, csource)
+
return csource, macros
def _common_type_names(csource):
@@ -219,17 +223,8 @@
value = value.strip()
if _r_int_literal.match(value):
self._add_integer_constant(key, value)
- elif value == '...':
+ else:
self._declare('macro ' + key, value)
- else:
- raise api.CDefError(
- 'only supports one of the following syntax:\n'
- ' #define %s ... (literally dot-dot-dot)\n'
- ' #define %s NUMBER (with NUMBER an integer'
- ' constant, decimal/hex/octal)\n'
- 'got:\n'
- ' #define %s %s'
- % (key, key, key, value))
def _declare_function(self, tp, quals, decl):
tp = self._get_type_pointer(tp, quals)
@@ -662,9 +657,10 @@
return CNAME_TO_LLTYPE[name]
class ParsedSource(object):
- def __init__(self, source, definitions):
+ def __init__(self, source, definitions, macros):
self.source = source
self.definitions = definitions
+ self.macros = macros
def cffi_to_lltype(obj):
from pypy.module.cpyext.api import cpython_struct
@@ -681,10 +677,15 @@
ctx = Parser()
ctx.parse(source)
defs = {}
+ macros = {}
for name, (obj, quals) in ctx._declarations.iteritems():
- if not name.startswith('typedef '):
- continue
- name = name[8:]
- assert name not in defs
- defs[name] = cffi_to_lltype(obj)
- return ParsedSource(source, defs)
+ if name.startswith('typedef '):
+ name = name[8:]
+ assert name not in defs
+ defs[name] = cffi_to_lltype(obj)
+ elif name.startswith('macro '):
+ name = name[6:]
+ assert name not in macros
+ macros[name] = obj
+
+ return ParsedSource(source, defs, macros)
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
@@ -22,3 +22,20 @@
decl = "typedef ssize_t Py_ssize_t;"
hdr = parse_source(decl)
assert hdr.definitions == {'Py_ssize_t': rffi.SSIZE_T}
+
+def test_macro():
+ decl = """
+ typedef ssize_t Py_ssize_t;
+
+ #define PyObject_HEAD \
+ Py_ssize_t ob_refcnt; \
+ Py_ssize_t ob_pypy_link; \
+
+ typedef struct {
+ PyObject_HEAD
+ double ob_fval;
+ } PyFloatObject;
+ """
+ hdr = parse_source(decl)
+ assert 'PyFloatObject' in hdr.definitions
+ assert 'PyObject_HEAD' in hdr.macros
More information about the pypy-commit
mailing list