Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r1845:4d94d2c57548
Date: 2015-04-26 14:11 +0200
http://bitbucket.org/cffi/cffi/changeset/4d94d2c57548/
Log: Hex/octal numbers in array lengths
diff --git a/_cffi1/parse_c_type.c b/_cffi1/parse_c_type.c
--- a/_cffi1/parse_c_type.c
+++ b/_cffi1/parse_c_type.c
@@ -69,6 +69,13 @@
return ('0' <= x && x <= '9');
}
+static int is_hex_digit(char x)
+{
+ return (('0' <= x && x <= '9') ||
+ ('A' <= x && x <= 'F') ||
+ ('a' <= x && x <= 'f'));
+}
+
static int is_ident_next(char x)
{
return (is_ident_first(x) || is_digit(x));
@@ -113,7 +120,9 @@
tok->kind = TOK_INTEGER;
tok->p = p;
tok->size = 1;
- while (is_digit(p[tok->size]))
+ if (p[1] == 'x' || p[1] == 'X')
+ tok->size = 2;
+ while (is_hex_digit(p[tok->size]))
tok->size++;
return;
}
@@ -332,15 +341,18 @@
if (tok->kind != TOK_CLOSE_BRACKET) {
size_t length;
int gindex;
+ char *endptr;
switch (tok->kind) {
case TOK_INTEGER:
errno = 0;
if (sizeof(length) > sizeof(unsigned long))
- length = strtoull(tok->p, NULL, 10);
+ length = strtoull(tok->p, &endptr, 0);
else
- length = strtoul(tok->p, NULL, 10);
+ length = strtoul(tok->p, &endptr, 0);
+ if (endptr != tok->p + tok->size)
+ return parse_error(tok, "invalid number");
if (errno == ERANGE || length > MAX_SSIZE_T)
return parse_error(tok, "number too large");
break;
diff --git a/_cffi1/test_parse_c_type.py b/_cffi1/test_parse_c_type.py
--- a/_cffi1/test_parse_c_type.py
+++ b/_cffi1/test_parse_c_type.py
@@ -316,3 +316,21 @@
assert parse("int[FIVE]") == [Prim(lib._CFFI_PRIM_INT), '->', Array(0), 5]
assert parse("int[ZERO]") == [Prim(lib._CFFI_PRIM_INT), '->', Array(0), 0]
parse_error("int[NEG]", "expected a positive integer constant", 4)
+
+def test_various_constant_exprs():
+ def array(n):
+ return [Prim(lib._CFFI_PRIM_CHAR), '->', Array(0), n]
+ assert parse("char[21]") == array(21)
+ assert parse("char[0x10]") == array(16)
+ assert parse("char[0X21]") == array(33)
+ assert parse("char[0Xb]") == array(11)
+ assert parse("char[0x1C]") == array(0x1C)
+ assert parse("char[0xc6]") == array(0xC6)
+ assert parse("char[010]") == array(8)
+ assert parse("char[021]") == array(17)
+ parse_error("char[08]", "invalid number", 5)
+ parse_error("char[1C]", "invalid number", 5)
+ parse_error("char[0C]", "invalid number", 5)
+ # not supported (really obscure):
+ # "char[+5]"
+ # "char['A']"
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit