Author: Alex Stapleton <[email protected]>
Branch: cmacros
Changeset: r2231:254fab3123e3
Date: 2015-07-25 12:04 +0100
http://bitbucket.org/cffi/cffi/changeset/254fab3123e3/

Log:    Add Parser._extract_macros and _clean_macros

        Will be used for adding #if support

diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -24,6 +24,7 @@
 _r_words = re.compile(r"\w+|\S")
 _parser_cache = None
 _r_int_literal = re.compile(r"-?0?x?[0-9a-f]+[lu]*$", re.IGNORECASE)
+_r_c_macro = re.compile(r"^\s*#")
 
 def _get_parser():
     global _parser_cache
@@ -104,6 +105,38 @@
         self._recomplete = []
         self._uses_new_feature = None
 
+    def _extract_macros(self, csource):
+        """
+        Extract macros from csource.
+
+        :returns: [(ln, macro), ...]
+        """
+
+        macros = []
+
+        for num, line in enumerate(csource.splitlines()):
+            if _r_c_macro.match(line):
+                macros.append((num, line))
+
+        return macros
+
+    def _clean_macros(self, csource):
+        """
+        Remove macros from the csource
+
+        :returns: csource minus any C macros
+        """
+
+        cleaned = []
+
+        for line in csource.splitlines():
+            if _r_c_macro.match(line):
+                cleaned.append("")
+            else:
+                cleaned.append(line)
+
+        return '\n'.join(cleaned)
+
     def _parse(self, csource):
         csource, macros = _preprocess(csource)
         # XXX: for more efficiency we would need to poke into the
@@ -122,7 +155,9 @@
         csourcelines = ['typedef int %s;' % typename for typename in typenames]
         csourcelines.append('typedef int __dotdotdot__;')
         csourcelines.append(csource)
+
         csource = '\n'.join(csourcelines)
+
         if lock is not None:
             lock.acquire()     # pycparser is not thread-safe...
         try:
diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py
--- a/testing/cffi0/test_parsing.py
+++ b/testing/cffi0/test_parsing.py
@@ -1,5 +1,6 @@
-import py, sys, re
+import py, sys, re, textwrap
 from cffi import FFI, FFIError, CDefError, VerificationError
+from cffi.cparser import Parser
 
 class FakeBackend(object):
 
@@ -142,6 +143,39 @@
         BType = ffi._get_cached_btype(type)
     assert str(BType) == '<func (<pointer to <int>>), <int>, False>'
 
+def test_extract_macros():
+    parser = Parser()
+    macros = parser._extract_macros("""
+    int x;
+    #if defined(FOO)
+    int y;
+    #endif
+    int z;
+    """)
+
+    assert macros == [
+        (2, "    #if defined(FOO)"),
+        (4, "    #endif")
+    ]
+
+def test_clean_macros():
+    parser = Parser()
+    clean = parser._clean_macros("""
+    int x;
+    #if defined(FOO)
+    int y;
+    #endif
+    int z;
+    """)
+
+    assert clean == """
+    int x;
+
+    int y;
+
+    int z;
+    """
+
 def test_remove_comments():
     ffi = FFI(backend=FakeBackend())
     ffi.cdef("""
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to