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