]> granicus.if.org Git - python/commitdiff
Code by Inyeol Lee, submitted to SF bug 595350, to implement
authorGuido van Rossum <guido@python.org>
Fri, 23 Aug 2002 18:21:28 +0000 (18:21 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 23 Aug 2002 18:21:28 +0000 (18:21 +0000)
the string/unicode method .replace() with a zero-lengt first argument.
Inyeol contributed tests for this too.

Lib/test/string_tests.py
Lib/test/test_descr.py
Lib/test/test_unicode.py
Objects/stringobject.c
Objects/unicodeobject.c

index a071f2008960cb04dfc2930365241f5dcdaec2dd..f2d685329e305d11ba4058dea5f9e8ddad05a0e3 100644 (file)
@@ -202,6 +202,10 @@ def run_method_tests(test):
     test('replace', 'one!two!three!', 'one@two@three@', '!', '@')
     test('replace', 'one!two!three!', 'one!two!three!', 'x', '@')
     test('replace', 'one!two!three!', 'one!two!three!', 'x', '@', 2)
+    test('replace', 'abc', '-a-b-c-', '', '-')
+    test('replace', 'abc', '-a-b-c', '', '-', 3)
+    test('replace', 'abc', 'abc', '', '-', 0)
+    test('replace', '', '', '', '')
     # Next three for SF bug 422088: [OSF1 alpha] string.replace(); died with
     # MemoryError due to empty result (platform malloc issue when requesting
     # 0 bytes).
index bedb9d2fb771efc03874556ddd5ccce8f13270e8..0c7def14fe21feef9a7d13abe0051299f938d54b 100644 (file)
@@ -2996,10 +2996,6 @@ def strops():
     except ValueError: pass
     else: raise TestFailed, "''.rindex('5') doesn't raise ValueError"
 
-    try: ''.replace('', '')
-    except ValueError: pass
-    else: raise TestFailed, "''.replace('', '') doesn't raise ValueError"
-
     try: '%(n)s' % None
     except TypeError: pass
     else: raise TestFailed, "'%(n)s' % None doesn't raise TypeError"
index 4efa39cae1548cd1444cc0115595ef1a7dd9ffad..90147eb5feea906b4716bd2024ce2b62b1529919 100644 (file)
@@ -210,12 +210,10 @@ test('replace', u'one!two!three!', u'one!two!three!', u'!', u'@', 0)
 test('replace', u'one!two!three!', u'one@two@three@', u'!', u'@')
 test('replace', u'one!two!three!', u'one!two!three!', u'x', u'@')
 test('replace', u'one!two!three!', u'one!two!three!', u'x', u'@', 2)
-try:
-    u"abc".replace(u"", u"x")
-except ValueError:
-    pass
-else:
-    raise TestFailed, "u.replace('', ...) should raise ValueError"
+test('replace', u'abc', u'-a-b-c-', u'', u'-')
+test('replace', u'abc', u'-a-b-c', u'', u'-', 3)
+test('replace', u'abc', u'abc', u'', u'-', 0)
+test('replace', u'', u'', u'', u'')
 
 test('startswith', u'hello', True, u'he')
 test('startswith', u'hello', True, u'hello')
index 9f413175463d115fbbe0f692b145725f8059a44e..0b79a06d58ab1a775c7b73d3003ad24b2125ab58 100644 (file)
@@ -2215,11 +2215,11 @@ mymemreplace(const char *str, int len,          /* input string */
        char *new_s;
        int nfound, offset, new_len;
 
-       if (len == 0 || pat_len > len)
+       if (len == 0 || (pat_len == 0 && sub_len == 0) || pat_len > len)
                goto return_same;
 
        /* find length of output string */
-       nfound = mymemcnt(str, len, pat, pat_len);
+       nfound = (pat_len > 0) ? mymemcnt(str, len, pat, pat_len) : len + 1;
        if (count < 0)
                count = INT_MAX;
        else if (nfound > count)
@@ -2242,25 +2242,38 @@ mymemreplace(const char *str, int len,          /* input string */
                        return NULL;
                out_s = new_s;
 
-               for (; count > 0 && len > 0; --count) {
-                       /* find index of next instance of pattern */
-                       offset = mymemfind(str, len, pat, pat_len);
-                       if (offset == -1)
-                               break;
-
-                       /* copy non matching part of input string */
-                       memcpy(new_s, str, offset);
-                       str += offset + pat_len;
-                       len -= offset + pat_len;
-
-                       /* copy substitute into the output string */
-                       new_s += offset;
-                       memcpy(new_s, sub, sub_len);
-                       new_s += sub_len;
+               if (pat_len > 0) {
+                       for (; nfound > 0; --nfound) {
+                               /* find index of next instance of pattern */
+                               offset = mymemfind(str, len, pat, pat_len);
+                               if (offset == -1)
+                                       break;
+
+                               /* copy non matching part of input string */
+                               memcpy(new_s, str, offset);
+                               str += offset + pat_len;
+                               len -= offset + pat_len;
+
+                               /* copy substitute into the output string */
+                               new_s += offset;
+                               memcpy(new_s, sub, sub_len);
+                               new_s += sub_len;
+                       }
+                       /* copy any remaining values into output string */
+                       if (len > 0)
+                               memcpy(new_s, str, len);
+               }
+               else {
+                       for (;;++str, --len) {
+                               memcpy(new_s, sub, sub_len);
+                               new_s += sub_len;
+                               if (--nfound <= 0) {
+                                       memcpy(new_s, str, len);
+                                       break;
+                               }
+                               *new_s++ = *str;
+                       }
                }
-               /* copy any remaining values into output string */
-               if (len > 0)
-                       memcpy(new_s, str, len);
        }
        *out_len = new_len;
        return out_s;
@@ -2317,10 +2330,6 @@ string_replace(PyStringObject *self, PyObject *args)
        else if (PyObject_AsCharBuffer(replobj, &repl, &repl_len))
                return NULL;
 
-       if (sub_len <= 0) {
-               PyErr_SetString(PyExc_ValueError, "empty pattern string");
-               return NULL;
-       }
        new_s = mymemreplace(str,len,sub,sub_len,repl,repl_len,count,&out_len);
        if (new_s == NULL) {
                PyErr_NoMemory();
index b2649365ae3803123e2b533eb20659ebcf2cffa8..6dea94f4798f93c4019b61e2c22a22dfd7dac664 100644 (file)
@@ -3494,11 +3494,6 @@ PyObject *replace(PyUnicodeObject *self,
 {
     PyUnicodeObject *u;
 
-    if (str1->length == 0) {
-       PyErr_SetString(PyExc_ValueError, "empty pattern string");
-       return NULL;
-    }
-
     if (maxcount < 0)
        maxcount = INT_MAX;
 
@@ -3549,19 +3544,30 @@ PyObject *replace(PyUnicodeObject *self,
             if (u) {
                 i = 0;
                 p = u->str;
-                while (i <= self->length - str1->length)
-                    if (Py_UNICODE_MATCH(self, i, str1)) {
-                        /* replace string segment */
+                if (str1->length > 0) {
+                    while (i <= self->length - str1->length)
+                        if (Py_UNICODE_MATCH(self, i, str1)) {
+                            /* replace string segment */
+                            Py_UNICODE_COPY(p, str2->str, str2->length);
+                            p += str2->length;
+                            i += str1->length;
+                            if (--n <= 0) {
+                                /* copy remaining part */
+                                Py_UNICODE_COPY(p, self->str+i, self->length-i);
+                                break;
+                            }
+                        } else
+                            *p++ = self->str[i++];
+                } else {
+                    while (n > 0) {
                         Py_UNICODE_COPY(p, str2->str, str2->length);
                         p += str2->length;
-                        i += str1->length;
-                        if (--n <= 0) {
-                            /* copy remaining part */
-                            Py_UNICODE_COPY(p, self->str+i, self->length-i);
+                        if (--n <= 0)
                             break;
-                        }
-                    } else
                         *p++ = self->str[i++];
+                    }
+                    Py_UNICODE_COPY(p, self->str+i, self->length-i);
+                }
             }
         }
     }