[pypy-commit] pypy ffi-backend: Enough to pass test_wchar.

arigo noreply at buildbot.pypy.org
Thu Jul 26 21:57:24 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r56483:bdc5a8e54948
Date: 2012-07-26 21:50 +0200
http://bitbucket.org/pypy/pypy/changeset/bdc5a8e54948/

Log:	Enough to pass test_wchar.

diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py
--- a/pypy/module/_cffi_backend/ctypearray.py
+++ b/pypy/module/_cffi_backend/ctypearray.py
@@ -34,8 +34,8 @@
 
     def unicode(self, cdataobj):
         if isinstance(self.ctitem, W_CTypePrimitiveUniChar):
-            XXX
-            s = rffi.charp2strn(cdataobj._cdata, cdataobj.get_array_length())
+            s = rffi.wcharp2unicoden(rffi.cast(rffi.CWCHARP, cdataobj._cdata),
+                                     cdataobj.get_array_length())
             keepalive_until_here(cdataobj)
             return self.space.wrap(s)
         return W_CTypePtrOrArray.unicode(self, cdataobj)
diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -126,7 +126,17 @@
                     # set the "must free" flag to 0
                     set_mustfree_flag(data, 0)
                 #
-                #XXX WCHAR unicode raises NotImplementedError
+                if argtype.is_unichar_ptr_or_array:
+                    try:
+                        space.unicode_w(w_obj)
+                    except OperationError:
+                        if not e.match(space, space.w_TypeError):
+                            raise
+                    else:
+                        # passing a unicode raises NotImplementedError for now
+                        raise OperationError(space.w_NotImplementedError,
+                                    space.wrap("automatic unicode-to-"
+                                               "'wchar_t *' conversion"))
                 #
                 argtype.convert_from_object(data, w_obj)
             resultdata = rffi.ptradd(buffer, cif_descr.exchange_result)
diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py
--- a/pypy/module/_cffi_backend/ctypeprim.py
+++ b/pypy/module/_cffi_backend/ctypeprim.py
@@ -33,6 +33,15 @@
                                   len(s), self.name)
         return ord(s[0])
 
+    def cast_unicode(self, w_ob):
+        space = self.space
+        s = space.unicode_w(w_ob)
+        if len(s) != 1:
+            raise operationerrfmt(space.w_TypeError,
+                      "cannot cast unicode string of length %d to ctype '%s'",
+                                  len(s), self.name)
+        return ord(s[0])
+
     def cast(self, w_ob):
         from pypy.module._cffi_backend import ctypeptr
         space = self.space
@@ -44,7 +53,9 @@
         elif space.isinstance_w(w_ob, space.w_str):
             value = self.cast_str(w_ob)
             value = r_ulonglong(value)
-        #XXX WCHAR space.w_unicode
+        elif space.isinstance_w(w_ob, space.w_unicode):
+            value = self.cast_unicode(w_ob)
+            value = r_ulonglong(value)
         else:
             value = misc.as_unsigned_long_long(space, w_ob, strict=False)
         w_cdata = cdataobj.W_CDataCasted(space, self.size, self)
@@ -96,7 +107,8 @@
 class W_CTypePrimitiveUniChar(W_CTypePrimitiveCharOrUniChar):
 
     def int(self, cdata):
-        XXX
+        unichardata = rffi.cast(rffi.CWCHARP, cdata)
+        return self.space.wrap(ord(unichardata[0]))
 
     def convert_to_object(self, cdata):
         unichardata = rffi.cast(rffi.CWCHARP, cdata)
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -101,7 +101,16 @@
         return W_CTypePtrOrArray.str(self, cdataobj)
 
     def unicode(self, cdataobj):
-        XXX
+        if self.is_unichar_ptr_or_array:
+            if not cdataobj._cdata:
+                space = self.space
+                raise operationerrfmt(space.w_RuntimeError,
+                                      "cannot use unicode() on %s",
+                                      space.str_w(cdataobj.repr()))
+            s = rffi.wcharp2unicode(rffi.cast(rffi.CWCHARP, cdataobj._cdata))
+            keepalive_until_here(cdataobj)
+            return self.space.wrap(s)
+        return W_CTypePtrOrArray.unicode(self, cdataobj)
 
     def newp(self, w_init):
         from pypy.module._cffi_backend import ctypeprim
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1431,7 +1431,7 @@
     #assert f(u'a\u1234b') == 3    -- not implemented
     py.test.raises(NotImplementedError, f, u'a\u1234b')
     #
-    if wchar4:
+    if wchar4 and not pyuni4:
         # try out-of-range wchar_t values
         x = cast(BWChar, 1114112)
         py.test.raises(ValueError, unicode, x)


More information about the pypy-commit mailing list