Author: Armin Rigo <[email protected]>
Branch: char16_char32_t
Changeset: r2953:ac2fc8661954
Date: 2017-05-31 15:47 +0200
http://bitbucket.org/cffi/cffi/changeset/ac2fc8661954/
Log: Tests and fixes
diff --git a/c/wchar_helper.h b/c/wchar_helper.h
--- a/c/wchar_helper.h
+++ b/c/wchar_helper.h
@@ -80,29 +80,31 @@
static PyObject *
_my_PyUnicode_FromChar16(const cffi_char16_t *w, Py_ssize_t size)
{
+ /* 'size' is the length of the 'w' array */
PyObject *result = PyUnicode_FromUnicode(NULL, size);
if (result != NULL) {
Py_UNICODE *u_base = PyUnicode_AS_UNICODE(result);
Py_UNICODE *u = u_base;
- Py_ssize_t consumed;
- while (size > 0) {
- cffi_char32_t ch = *w++;
- size--;
- if (0xD800 <= ch && ch <= 0xDBFF && size > 0) {
- cffi_char32_t ch2 = *w;
- if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
- ch = (((ch & 0x3FF)<<10) | (ch2 & 0x3FF)) + 0x10000;
- w++;
- size--;
+ if (size == 1) { /* performance only */
+ *u = (cffi_char32_t)*w;
+ }
+ else {
+ while (size > 0) {
+ cffi_char32_t ch = *w++;
+ size--;
+ if (0xD800 <= ch && ch <= 0xDBFF && size > 0) {
+ cffi_char32_t ch2 = *w;
+ if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {
+ ch = (((ch & 0x3FF)<<10) | (ch2 & 0x3FF)) + 0x10000;
+ w++;
+ size--;
+ }
}
+ *u++ = ch;
}
- *u++ = ch;
- }
- consumed = u - u_base;
- if (consumed < size) {
- if (PyUnicode_Resize(&result, consumed) < 0) {
+ if (PyUnicode_Resize(&result, u - u_base) < 0) {
Py_DECREF(result);
return NULL;
}
diff --git a/cffi/cffi_opcode.py b/cffi/cffi_opcode.py
--- a/cffi/cffi_opcode.py
+++ b/cffi/cffi_opcode.py
@@ -107,9 +107,10 @@
PRIM_UINTMAX = 47
PRIM_FLOATCOMPLEX = 48
PRIM_DOUBLECOMPLEX = 49
+PRIM_CHAR16 = 50
+PRIM_CHAR32 = 51
-
-_NUM_PRIM = 50
+_NUM_PRIM = 52
_UNKNOWN_PRIM = -1
_UNKNOWN_FLOAT_PRIM = -2
_UNKNOWN_LONG_DOUBLE = -3
@@ -135,6 +136,8 @@
'double _Complex': PRIM_DOUBLECOMPLEX,
'_Bool': PRIM_BOOL,
'wchar_t': PRIM_WCHAR,
+ 'char16_t': PRIM_CHAR16,
+ 'char32_t': PRIM_CHAR32,
'int8_t': PRIM_INT8,
'uint8_t': PRIM_UINT8,
'int16_t': PRIM_INT16,
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -122,6 +122,8 @@
'_Bool': 'i',
# the following types are not primitive in the C sense
'wchar_t': 'c',
+ 'char16_t': 'c',
+ 'char32_t': 'c',
'int8_t': 'i',
'uint8_t': 'i',
'int16_t': 'i',
diff --git a/testing/cffi0/test_ffi_backend.py
b/testing/cffi0/test_ffi_backend.py
--- a/testing/cffi0/test_ffi_backend.py
+++ b/testing/cffi0/test_ffi_backend.py
@@ -1,6 +1,7 @@
import py, sys, platform
import pytest
from testing.cffi0 import backend_tests, test_function, test_ownlib
+from testing.support import u
from cffi import FFI
import _cffi_backend
@@ -397,6 +398,8 @@
"double",
"long double",
"wchar_t",
+ "char16_t",
+ "char32_t",
"_Bool",
"int8_t",
"uint8_t",
@@ -508,3 +511,38 @@
py.test.raises(TypeError, cd)
py.test.raises(TypeError, cd, ffi.NULL)
py.test.raises(TypeError, cd, ffi.typeof("void *"))
+
+ def test_explicitly_defined_char16_t(self):
+ ffi = FFI()
+ ffi.cdef("typedef uint16_t char16_t;")
+ x = ffi.cast("char16_t", 1234)
+ assert ffi.typeof(x) is ffi.typeof("uint16_t")
+
+ def test_char16_t(self):
+ ffi = FFI()
+ x = ffi.new("char16_t[]", 5)
+ assert len(x) == 5 and ffi.sizeof(x) == 10
+ x[2] = u+'\u1324'
+ assert x[2] == u+'\u1324'
+ y = ffi.new("char16_t[]", u+'\u1234\u5678')
+ assert len(y) == 3
+ assert list(y) == [u+'\u1234', u+'\u5678', u+'\x00']
+ assert ffi.string(y) == u+'\u1234\u5678'
+ z = ffi.new("char16_t[]", u+'\U00012345')
+ assert len(z) == 3
+ assert list(z) == [u+'\ud808', u+'\udf45', u+'\x00']
+ assert ffi.string(z) == u+'\U00012345'
+
+ def test_char32_t(self):
+ ffi = FFI()
+ x = ffi.new("char32_t[]", 5)
+ assert len(x) == 5 and ffi.sizeof(x) == 20
+ x[3] = u+'\U00013245'
+ assert x[3] == u+'\U00013245'
+ y = ffi.new("char32_t[]", u+'\u1234\u5678')
+ assert len(y) == 3
+ assert list(y) == [u+'\u1234', u+'\u5678', u+'\x00']
+ z = ffi.new("char32_t[]", u+'\U00012345')
+ assert len(z) == 2
+ assert list(z) == [u+'\U00012345', u+'\x00'] # maybe a 2-unichars
string
+ assert ffi.string(z) == u+'\U00012345'
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -2250,3 +2250,9 @@
int f(int a) { return a + 40; }
""", extra_compile_args=['-fvisibility=hidden'])
assert lib.f(2) == 42
+
+def test_override_default_definition():
+ ffi = FFI()
+ ffi.cdef("typedef long int16_t, char16_t;")
+ lib = verify(ffi, "test_override_default_definition", "")
+ assert ffi.typeof("int16_t") is ffi.typeof("char16_t") is
ffi.typeof("long")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit