[pypy-svn] r52099 - in pypy/dist/pypy/rpython: lltypesystem test

arigo at codespeak.net arigo at codespeak.net
Mon Mar 3 19:08:57 CET 2008


Author: arigo
Date: Mon Mar  3 19:08:56 2008
New Revision: 52099

Modified:
   pypy/dist/pypy/rpython/lltypesystem/rstr.py
   pypy/dist/pypy/rpython/test/test_rstr.py
Log:
Fixes for RPython strings: find(), rfind(), count() now accept
endpos arguments that are larger than the length of the string,
just like slicing.


Modified: pypy/dist/pypy/rpython/lltypesystem/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rstr.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rstr.py	Mon Mar  3 19:08:56 2008
@@ -445,6 +445,8 @@
 
     def ll_find_char(s, ch, start, end):
         i = start
+        if end > len(s.chars):
+            end = len(s.chars)
         while i < end:
             if s.chars[i] == ch:
                 return i
@@ -452,6 +454,8 @@
         return -1
 
     def ll_rfind_char(s, ch, start, end):
+        if end > len(s.chars):
+            end = len(s.chars)
         i = end
         while i > start:
             i -= 1
@@ -462,6 +466,8 @@
     def ll_count_char(s, ch, start, end):
         count = 0
         i = start
+        if end > len(s.chars):
+            end = len(s.chars)
         while i < end:
             if s.chars[i] == ch:
                 count += 1
@@ -470,12 +476,12 @@
 
     def ll_find(cls, s1, s2, start, end):
         """Knuth Morris Prath algorithm for substring match"""
-        len1 = len(s1.chars)
-        if end > len1:
-            end = len1
         len2 = len(s2.chars)
         if len2 == 1:
             return cls.ll_find_char(s1, s2.chars[0], start, end)
+        len1 = len(s1.chars)
+        if end > len1:
+            end = len1
         if len2 == 0:
             if (end-start) < 0:
                 return -1
@@ -507,10 +513,9 @@
         len2 = len(s2.chars)
         if len2 == 1:
             return cls.ll_rfind_char(s1, s2.chars[0], start, end)
+        if end > len(s1.chars):
+            end = len(s1.chars)
         if len2 == 0:
-            len1 = len(s1.chars)
-            if end > len(s1.chars):
-                return len1
             return end
         # Construct the array of possible restarting positions
         T = malloc( SIGNED_ARRAY, len2 )

Modified: pypy/dist/pypy/rpython/test/test_rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rstr.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rstr.py	Mon Mar  3 19:08:56 2008
@@ -265,8 +265,9 @@
         def fn(i, j):
             assert i >= 0
             assert j >= 0
-            return const('ababcabc').find(const('abc'), i, j)
-        for (i, j) in [(1,7), (2,6), (3,7), (3,8)]:
+            return (const('ababcabc').find(const('abc'), i, j) +
+                    const('ababcabc').find('b', i, j) * 100)
+        for (i, j) in [(1,7), (2,6), (3,7), (3,8), (4,99), (7, 99)]:
             res = self.interpret(fn, [i, j])
             assert res == fn(i, j)
 
@@ -287,9 +288,18 @@
     def test_rfind(self):
         const = self.const
         def fn():
-            return const('aaa').rfind(const('a')) + const('aaa').rfind(const('a'), 1) + const('aaa').rfind(const('a'), 1, 2)
+            # string-searching versions
+            return (const('aaa').rfind(const('aa')) +
+                    const('aaa').rfind(const('aa'), 1) * 10 +
+                    const('aaa').rfind(const('aa'), 1, 2) * 100 +
+                    const('aaa').rfind(const('aa'), 3, 42) * 1000 +
+            # char-searching versions
+                    const('aaa').rfind('a') * 10000 +
+                    const('aaa').rfind('a', 1) * 100000 +
+                    const('aaa').rfind('a', 1, 2) * 1000000 +
+                    const('aaa').rfind('a', 3, 42) * 10000000)
         res = self.interpret(fn, [])
-        assert res == 2 + 2 + 1
+        assert res == fn()
 
     def test_rfind_empty_string(self):
         const = self.const
@@ -680,9 +690,9 @@
         def fn(i):
             s = const("").join([const("abcasd")] * i)
             return s.count(const("a")) + s.count(const("a"), 2) + \
-                   s.count(const("b"), 1, 6)
+                   s.count(const("b"), 1, 6) + s.count(const("a"), 5, 99)
         res = self.interpret(fn, [4])
-        assert res == 8 + 7 + 1
+        assert res == 8 + 7 + 1 + 6
 
     def test_count(self):
         const = self.const
@@ -690,9 +700,10 @@
             s = const("").join([const("abcabsd")] * i)
             one = i / i # confuse the annotator
             return (s.count(const("abc")) + const("abcde").count(const("")) +
-                    const("abcda").count(const("a") * one))
+                    const("abcda").count(const("a") * one) +
+                    s.count(const("ab"), 0, 999))
         res = self.interpret(fn, [4])
-        assert res == 4 + 6 + 2
+        assert res == 4 + 6 + 2 + 8
 
     def test_count_overlapping_occurences(self):
         const = self.const


More information about the pypy-svn mailing list