[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