diff options
author | guillaumesottas <guillaumesottas@Guillaumes-MacBook-Pro.local> | 2019-03-26 13:09:18 -0600 |
---|---|---|
committer | guillaumesottas <guillaumesottas@Guillaumes-MacBook-Pro.local> | 2019-03-26 13:09:18 -0600 |
commit | 23f4b0b03bb5acf8c4770979d45dceda3e056fe4 (patch) | |
tree | aadad91539e1baa7974211ebabe5fa55547ff78e | |
parent | 21e166d3a7641bda5821f23c3d6cc349585d1697 (diff) | |
download | cffi-23f4b0b03bb5acf8c4770979d45dceda3e056fe4.tar.gz |
add support for long/long long C integer constant suffixes, and support
for base 2 integer constant as well.
-rw-r--r-- | cffi/cparser.py | 22 | ||||
-rw-r--r-- | testing/cffi0/test_parsing.py | 39 |
2 files changed, 52 insertions, 9 deletions
diff --git a/cffi/cparser.py b/cffi/cparser.py index 474f756..a8e390e 100644 --- a/cffi/cparser.py +++ b/cffi/cparser.py @@ -817,12 +817,22 @@ class Parser(object): # or positive/negative number if isinstance(exprnode, pycparser.c_ast.Constant): s = exprnode.value - if s.startswith('0'): - if s.startswith('0x') or s.startswith('0X'): - if s.endswith('u') or s.endswith('U'): - s = s[:-1] - return int(s, 16) - return int(s, 8) + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') # remove integer constant suffix if any. this will remove pattern such as lL, but + # it is the responsibility of the C parser to perform this check. + try: # first we try to convert to base 8/10, as it will fail if the string contains base 2/16 C prefix. + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: # then it should be a base 2 or a base 16. it is necessary to explicitly check the + # prefix, as python's int() function will be able to convert both (0b01 and 0x0b01) into base 16. + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) elif '1' <= s[0] <= '9': return int(s, 10) elif s[0] == "'" and s[-1] == "'" and ( diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py index c06c4b6..0255d70 100644 --- a/testing/cffi0/test_parsing.py +++ b/testing/cffi0/test_parsing.py @@ -470,6 +470,39 @@ def test_error_invalid_syntax_for_cdef(): def test_unsigned_int_suffix_for_constant(): ffi = FFI() ffi.cdef("""enum e { - enumerator_0=0x00, - enumerator_1=0x01u, - enumerator_1=0x01U};""") + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + try: + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result + except AssertionError as e: + raise e |