[pypy-svn] r25669 - in pypy/dist/pypy/rpython: lltypesystem rctypes rctypes/test
arigo at codespeak.net
arigo at codespeak.net
Mon Apr 10 17:43:29 CEST 2006
Author: arigo
Date: Mon Apr 10 17:43:27 2006
New Revision: 25669
Modified:
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/rctypes/rchar_p.py
pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
Log:
Hack in lltype to allow __getitem__ just past the end of rpystrings
to return the hidden final \x00 character. This allows some good
progress on string support in rctypes.
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Mon Apr 10 17:43:27 2006
@@ -763,6 +763,11 @@
def __getitem__(self, i): # ! can only return basic or ptr !
if isinstance(self._T, (Array, FixedSizeArray)):
if not (0 <= i < self._obj.getlength()):
+ if (self._T._hints.get('isrpystring', False) and
+ i == self._obj.getlength()):
+ # special hack for the null terminator
+ assert self._T.OF == Char
+ return '\x00'
raise IndexError("array index out of bounds")
o = self._obj.getitem(i)
return _expose(o, self._solid)
@@ -792,6 +797,12 @@
return self._obj.getlength()
raise TypeError("%r instance is not an array" % (self._T,))
+ def __iter__(self):
+ # this is a work-around for the 'isrpystring' hack in __getitem__,
+ # which otherwise causes list(p) to include the extra \x00 character.
+ for i in range(len(self)):
+ yield self[i]
+
def __repr__(self):
return '<%s>' % (self,)
Modified: pypy/dist/pypy/rpython/rctypes/rchar_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rchar_p.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rchar_p.py Mon Apr 10 17:43:27 2006
@@ -1,8 +1,9 @@
from pypy.rpython import extregistry
from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.rpython.rstr import string_repr
+from pypy.rpython.rstr import StringRepr, string_repr
from pypy.rpython.rctypes.rmodel import CTypesValueRepr
from pypy.annotation import model as annmodel
+from pypy.annotation.pairtype import pairtype
from ctypes import c_char_p
@@ -41,6 +42,16 @@
self.setstring(hop.llops, v_char_p, v_value)
+class __extend__(pairtype(StringRepr, CCharPRepr)):
+ def convert_from_to((r_from, r_to), v, llops):
+ # r_from could be char_repr: first convert it to string_repr
+ v = llops.convertvar(v, r_from, string_repr)
+ r_temp = r_to.r_memoryowner
+ v_owned_box = r_temp.allocate_instance(llops)
+ r_temp.setstring(llops, v_owned_box, v)
+ return llops.convertvar(v_owned_box, r_temp, r_to)
+
+
CCHARP = llmemory.Address # char *
FIRSTITEMOFS = llmemory.ArrayItemsOffset(string_repr.lowleveltype.TO.chars)
@@ -62,7 +73,7 @@
def ll_getstring(box):
p = box.c_data.value
if p:
- if (box.keepalive_str and ll_str2charp(box.keepalive_str) == p):
+ if box.keepalive_str and ll_str2charp(box.keepalive_str) == p:
maxlen = len(box.keepalive_str.chars)
length = ll_strnlen(p, maxlen)
if length == maxlen:
Modified: pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py Mon Apr 10 17:43:27 2006
@@ -16,7 +16,7 @@
except ImportError:
py.test.skip("this test needs ctypes installed")
-from ctypes import c_char_p
+from ctypes import c_char_p, pointer
class Test_annotation:
def test_annotate_c_char_p(self):
@@ -60,6 +60,28 @@
res = interpret(func, [])
assert ''.join(res.chars) == "hello"
+ def test_zero_terminates(self):
+ def func():
+ p = c_char_p('world')
+ p.value = "hello\x00world"
+ return p.value
+
+ res = interpret(func, [])
+ assert ''.join(res.chars) == "hello"
+
+ def test_pointer_access(self):
+ def func():
+ q = c_char_p('ka')
+ p = c_char_p('world')
+ pp = pointer(p)
+ pp[0] = q.value
+ return p.value
+
+ assert func() == 'ka'
+ res = interpret(func, [])
+ assert ''.join(res.chars) == 'ka'
+
+
class Test_compilation:
def test_compile_c_char_p(self):
def func():
Modified: pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py Mon Apr 10 17:43:27 2006
@@ -5,6 +5,7 @@
from pypy.translator.c.test.test_genc import compile
from pypy import conftest
from pypy.rpython.rstr import string_repr
+from pypy.rpython.lltypesystem import lltype, llmemory
from ctypes import c_int, c_long, c_char_p
@@ -19,14 +20,11 @@
atoi = mylib.atoi
atoi.restype = c_int
atoi.argtypes = [c_char_p]
-def ll_atoi(s):
+def ll_atoi(s_addr):
"Very approximative ll implementation of atoi(), for testing"
i = result = 0
- while i < len(s.chars):
- if '0' <= s.chars[i] <= '9':
- result = result * 10 + ord(s.chars[i]) - ord('0')
- else:
- break
+ while '0' <= s_addr.char[i] <= '9':
+ result = result * 10 + ord(s_addr.char[i]) - ord('0')
i += 1
return result
atoi.llinterp_friendly_version = ll_atoi
@@ -39,10 +37,16 @@
return labs(n)
def test_ll_atoi():
- assert ll_atoi(string_repr.convert_const("")) == 0
- assert ll_atoi(string_repr.convert_const("42z7")) == 42
- assert ll_atoi(string_repr.convert_const("blah")) == 0
- assert ll_atoi(string_repr.convert_const("18238")) == 18238
+ keepalive = []
+ def str2addr(string):
+ llstring = string_repr.convert_const(string)
+ keepalive.append(llstring)
+ return (llmemory.cast_ptr_to_adr(llstring.chars) +
+ llmemory.ArrayItemsOffset(lltype.typeOf(llstring.chars).TO))
+ assert ll_atoi(str2addr("")) == 0
+ assert ll_atoi(str2addr("42z7")) == 42
+ assert ll_atoi(str2addr("blah")) == 0
+ assert ll_atoi(str2addr("18238")) == 18238
class Test_annotation:
def test_annotate_labs(self):
@@ -67,7 +71,6 @@
assert res == 11
def test_specialize_atoi(self):
- py.test.skip("in-progress")
choices = ["", "42z7", "blah", "18238"]
def fn(n):
return atoi(choices[n])
More information about the Pypy-commit
mailing list