[pypy-commit] pypy ffi-backend: Enums.

arigo noreply at buildbot.pypy.org
Mon Jun 25 18:19:56 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r55822:87f261b975b8
Date: 2012-06-25 18:19 +0200
http://bitbucket.org/pypy/pypy/changeset/87f261b975b8/

Log:	Enums.

diff --git a/pypy/module/_ffi_backend/ctypeobj.py b/pypy/module/_ffi_backend/ctypeobj.py
--- a/pypy/module/_ffi_backend/ctypeobj.py
+++ b/pypy/module/_ffi_backend/ctypeobj.py
@@ -295,7 +295,7 @@
     def _alignof(self):
         return self.align
 
-    def cast_single_char(self, w_ob):
+    def cast_str(self, w_ob):
         space = self.space
         s = space.str_w(w_ob)
         if len(s) != 1:
@@ -311,7 +311,7 @@
                isinstance(ob.ctype, W_CTypePtrOrArray)):
             value = rffi.cast(lltype.Signed, ob._cdata)
         elif space.isinstance_w(w_ob, space.w_str):
-            value = self.cast_single_char(w_ob)
+            value = self.cast_str(w_ob)
         elif space.is_w(w_ob, space.w_None):
             value = 0
         else:
@@ -378,7 +378,6 @@
 
     def convert_to_object(self, cdata):
         value = misc.read_raw_signed_data(cdata, self.size)
-        # xxx enum
         if self.value_fits_long:
             return self.space.wrap(intmask(value))
         else:
@@ -386,7 +385,6 @@
 
     def convert_from_object(self, cdata, w_ob):
         value = misc.as_long_long(self.space, w_ob)
-        # xxx enums
         if self.size < rffi.sizeof(lltype.SignedLongLong):
             if r_ulonglong(value) - self.vmin > self.vrangemax:
                 self._overflow(w_ob)
@@ -433,7 +431,7 @@
             w_ob = ob.convert_to_object()
         #
         if space.isinstance_w(w_ob, space.w_str):
-            value = self.cast_single_char(w_ob)
+            value = self.cast_str(w_ob)
         elif space.is_w(w_ob, space.w_None):
             value = 0.0
         else:
@@ -485,6 +483,53 @@
         space.call_method(w_lst, 'sort')
         return w_lst
 
+    def try_str(self, cdataobj):
+        w_res = self.convert_to_object(cdataobj._cdata)
+        keepalive_until_here(cdataobj)
+        return w_res
+
+    def convert_to_object(self, cdata):
+        value = intmask(misc.read_raw_signed_data(cdata, self.size))
+        try:
+            enumerator = self.enumvalues2erators[value]
+        except KeyError:
+            enumerator = '#%d' % (value,)
+        return self.space.wrap(enumerator)
+
+    def convert_from_object(self, cdata, w_ob):
+        space = self.space
+        try:
+            return W_CTypePrimitiveSigned.convert_from_object(self, cdata,
+                                                              w_ob)
+        except OperationError, e:
+            if not e.match(space, space.w_TypeError):
+                raise
+        if space.isinstance_w(w_ob, space.w_str):
+            value = self.convert_enum_string_to_int(space.str_w(w_ob))
+            misc.write_raw_integer_data(cdata, value, self.size)
+        else:
+            raise self._convert_error("str or int", w_ob)
+
+    def cast_str(self, w_ob):
+        space = self.space
+        return self.convert_enum_string_to_int(space.str_w(w_ob))
+
+    def convert_enum_string_to_int(self, s):
+        space = self.space
+        if s.startswith('#'):
+            try:
+                return int(s[1:])     # xxx is it RPython?
+            except ValueError:
+                raise OperationError(space.w_ValueError,
+                                     space.wrap("invalid literal after '#'"))
+        else:
+            try:
+                return self.enumerators2values[s]
+            except KeyError:
+                raise operationerrfmt(space.w_ValueError,
+                                      "'%s' is not an enumerator for %s",
+                                      s, self.name)
+
 
 class W_CTypeStructOrUnion(W_CType):
     # fields added by complete_struct_or_union():


More information about the pypy-commit mailing list