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

Reply via email to