[pypy-svn] r25878 - in pypy/dist/pypy/rpython: . rctypes rctypes/test

arigo at codespeak.net arigo at codespeak.net
Mon Apr 17 12:44:52 CEST 2006


Author: arigo
Date: Mon Apr 17 12:44:45 2006
New Revision: 25878

Modified:
   pypy/dist/pypy/rpython/rctypes/aarray.py
   pypy/dist/pypy/rpython/rctypes/rarray.py
   pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
   pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
   pypy/dist/pypy/rpython/rptr.py
Log:
'value' attribute of char arrays.


Modified: pypy/dist/pypy/rpython/rctypes/aarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/aarray.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/aarray.py	Mon Apr 17 12:44:45 2006
@@ -1,5 +1,5 @@
-from ctypes import ARRAY, c_int
-from pypy.annotation.model import SomeCTypesObject, SomeBuiltin
+from ctypes import ARRAY, c_int, c_char
+from pypy.annotation.model import SomeCTypesObject, SomeBuiltin, SomeString
 from pypy.rpython import extregistry
 from pypy.rpython.lltypesystem import lltype
 
@@ -28,6 +28,12 @@
     from pypy.rpython.rctypes.rarray import ArrayRepr
     return ArrayRepr(rtyper, s_array)
 
-extregistry.register_metatype(ArrayType,
+entry = extregistry.register_metatype(ArrayType,
     compute_annotation=array_instance_compute_annotation,
     get_repr=arraytype_get_repr)
+def char_array_get_field_annotation(s_array, fieldname):
+    assert fieldname == 'value'
+    if s_array.knowntype._type_ != c_char:
+        raise Exception("only arrays of chars have a .value attribute")
+    return SomeString()   # can_be_None = False
+entry.get_field_annotation = char_array_get_field_annotation

Modified: pypy/dist/pypy/rpython/rctypes/rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rarray.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rarray.py	Mon Apr 17 12:44:45 2006
@@ -1,5 +1,6 @@
 from ctypes import ARRAY, c_int
 from pypy.rpython.rbuiltin import gen_cast_subarray_pointer
+from pypy.rpython.rstr import string_repr
 from pypy.rpython.rmodel import IntegerRepr, inputconst
 from pypy.rpython.lltypesystem import lltype
 from pypy.annotation.pairtype import pairtype
@@ -38,6 +39,14 @@
                 # ByValue case
                 p.c_data[i] = llitem.c_data[0]
 
+    def rtype_getattr(self, hop):
+        s_attr = hop.args_s[1]
+        assert s_attr.is_constant()
+        assert s_attr.const == 'value'
+        assert self.r_item.ll_type == lltype.Char  # .value: char arrays only
+        v_box = hop.inputarg(self, 0)
+        return hop.gendirectcall(ll_chararrayvalue, v_box)
+
     def get_c_data_of_item(self, llops, v_array, v_index):
         v_c_array = self.get_c_data(llops, v_array)
         if isinstance(self.r_item, CTypesRefRepr):
@@ -89,3 +98,14 @@
             # ByValue case (optimization; the above also works in this case)
             v_newvalue = r_array.r_item.getvalue(hop.llops, v_item)
             r_array.set_item_value(hop.llops, v_array, v_index, v_newvalue)
+
+
+def ll_chararrayvalue(box):
+    from pypy.rpython.rctypes import rchar_p
+    p = box.c_data
+    p1 = lltype.cast_subarray_pointer(rchar_p.CCHARP, p, 0)
+    length = rchar_p.ll_strnlen(p1, len(p))
+    newstr = lltype.malloc(string_repr.lowleveltype.TO, length)
+    for i in range(length):
+        newstr.chars[i] = p[i]
+    return newstr

Modified: pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py	Mon Apr 17 12:44:45 2006
@@ -89,3 +89,30 @@
     p1 = cast(pointer(x), c_void_p)
     p2 = cast(p1, POINTER(c_int))
     assert p2.contents.value == 12
+
+def test_char_array():
+    a = (c_char * 3)()
+    a[0] = 'x'
+    a[1] = 'y'
+    assert a.value == 'xy'
+    a[2] = 'z'
+    assert a.value == 'xyz'
+
+    b = create_string_buffer(3)
+    assert type(b) is type(a)
+
+    b.value = "nxw"
+    assert b[0] == 'n'
+    assert b[1] == 'x'
+    assert b[2] == 'w'
+
+    b.value = "?"
+    assert b[0] == '?'
+    assert b[1] == '\x00'
+    assert b[2] == 'w'
+
+    class S(Structure):
+        _fields_ = [('p', POINTER(c_char))]
+
+    s = S()
+    s.p = b

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rarray.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rarray.py	Mon Apr 17 12:44:45 2006
@@ -4,6 +4,7 @@
 
 import py.test
 import pypy.rpython.rctypes.implementation
+from pypy.annotation import model as annmodel
 from pypy.annotation.annrpython import RPythonAnnotator
 from pypy.translator.translator import TranslationContext
 from pypy import conftest
@@ -16,7 +17,7 @@
 except ImportError:
     py.test.skip("this test needs ctypes installed")
 
-from ctypes import c_int, c_short, ARRAY, POINTER, pointer, c_char_p
+from ctypes import c_int, c_short, ARRAY, POINTER, pointer, c_char_p, c_char
 
 c_int_10 = ARRAY(c_int,10)
 
@@ -146,6 +147,20 @@
             a.translator.view()
         assert s.knowntype == int
 
+    def test_annotate_char_array_value(self):
+        A = c_char * 3
+        def func():
+            a = A()
+            a[0] = 'x'
+            a[1] = 'y'
+            return a.value
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(func, [])
+        if conftest.option.view:
+            a.translator.view()
+        assert s == annmodel.SomeString()
+
 class Test_specialization:
     def test_specialize_array(self):
         def create_array():
@@ -190,6 +205,16 @@
         res = interpret(func, [])
         assert res == expected
 
+    def test_specialize_char_array_value(self):
+        A = c_char * 3
+        def func():
+            a = A()
+            a[0] = 'x'
+            a[1] = 'y'
+            return a.value
+        res = interpret(func, [])
+        assert ''.join(res.chars) == "xy"
+
 class Test_compilation:
     def test_compile_array_access(self):
         def access_array():
@@ -221,3 +246,13 @@
         func, expected = maketest()
         fn = compile(func, [])
         assert fn() == expected
+
+    def test_compile_char_array_value(self):
+        A = c_char * 3
+        def func():
+            a = A()
+            a[0] = 'x'
+            a[1] = 'y'
+            return a.value
+        fn = compile(func, [])
+        assert fn() == "xy"

Modified: pypy/dist/pypy/rpython/rptr.py
==============================================================================
--- pypy/dist/pypy/rpython/rptr.py	(original)
+++ pypy/dist/pypy/rpython/rptr.py	Mon Apr 17 12:44:45 2006
@@ -2,7 +2,7 @@
 from pypy.annotation import model as annmodel
 from pypy.objspace.flow import model as flowmodel
 from pypy.rpython.lltypesystem.lltype import \
-     Ptr, ContainerType, Void, Signed, Bool, FuncType, typeOf
+     Ptr, ContainerType, Void, Signed, Bool, FuncType, typeOf, FixedSizeArray
 from pypy.rpython.error import TyperError
 from pypy.rpython.rmodel import Repr, IntegerRepr
 
@@ -47,9 +47,13 @@
         hop.genop('setfield', vlist)
 
     def rtype_len(self, hop):
-        vlist = hop.inputargs(self)
-        return hop.genop('getarraysize', vlist,
-                         resulttype = hop.r_result.lowleveltype)
+        ARRAY = hop.args_r[0].lowleveltype.TO
+        if isinstance(ARRAY, FixedSizeArray):
+            return hop.inputconst(Signed, ARRAY.length)
+        else:
+            vlist = hop.inputargs(self)
+            return hop.genop('getarraysize', vlist,
+                             resulttype = hop.r_result.lowleveltype)
 
     def rtype_is_true(self, hop):
         vlist = hop.inputargs(self)



More information about the Pypy-commit mailing list