Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2c6a6e5

Browse files
committed
Implement rpartition method
1 parent 247281a commit 2c6a6e5

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/cstring.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
#include <Python.h>
22

33

4-
/*
5-
* memrchr not available on some systems, so reimplement.
6-
*/
4+
/* memrchr not available on some systems, so reimplement. */
75
const char *_memrchr(const char *s, int c, size_t n) {
86
for(const char *p = s + n - 1; p >= s; --p) {
97
if(*p == c)
@@ -12,6 +10,14 @@ const char *_memrchr(const char *s, int c, size_t n) {
1210
return NULL;
1311
}
1412

13+
const char *_strrstr(const char *s, const char *find) {
14+
const char *p = s + strlen(s) - 1;
15+
for(;p > s; --p) {
16+
if(memcmp(p, find, strlen(find)) == 0)
17+
return p;
18+
}
19+
return NULL;
20+
}
1521

1622

1723
struct cstring {
@@ -584,6 +590,29 @@ PyObject *cstring_partition(PyObject *self, PyObject *arg) {
584590
_cstring_new(Py_TYPE(self), right, &CSTRING_LAST_BYTE(self) - right));
585591
}
586592

593+
PyDoc_STRVAR(rpartition__doc__, "");
594+
PyObject *cstring_rpartition(PyObject *self, PyObject *arg) {
595+
if(!_ensure_cstring(arg))
596+
return NULL;
597+
598+
const char *search = CSTRING_VALUE(arg);
599+
600+
const char *left = CSTRING_VALUE(self);
601+
const char *mid = _strrstr(left, search);
602+
if(!mid) {
603+
return _tuple_steal_refs(3,
604+
cstring_new_empty(),
605+
cstring_new_empty(),
606+
(Py_INCREF(self), self));
607+
}
608+
const char *right = mid + strlen(search);
609+
610+
return _tuple_steal_refs(3,
611+
_cstring_new(Py_TYPE(self), left, mid - left),
612+
_cstring_new(Py_TYPE(self), mid, right - mid),
613+
_cstring_new(Py_TYPE(self), right, &CSTRING_LAST_BYTE(self) - right));
614+
}
615+
587616
PyDoc_STRVAR(rfind__doc__, "");
588617
PyObject *cstring_rfind(PyObject *self, PyObject *args) {
589618
struct _substr_params params;
@@ -778,7 +807,7 @@ static PyMethodDef cstring_methods[] = {
778807
{"rfind", cstring_rfind, METH_VARARGS, rfind__doc__},
779808
{"rindex", cstring_rindex, METH_VARARGS, rindex__doc__},
780809
/* TODO: rjust */
781-
/* TODO: rpartition */
810+
{"rpartition", cstring_rpartition, METH_O, rpartition__doc__},
782811
/* TODO: rsplit */
783812
{"rstrip", cstring_rstrip, METH_VARARGS, rstrip__doc__},
784813
/* TODO: split */

test/test_methods.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,18 @@ def test_partition_sep_not_found():
227227
assert target.partition(cstring(': ')) == result
228228

229229

230+
def test_rpartition():
231+
target = cstring('hello, world')
232+
result = (cstring('hello, wor'), cstring('l'), cstring('d'))
233+
assert target.rpartition(cstring('l')) == result
234+
235+
236+
def test_rpartition_sep_not_found():
237+
target = cstring('hello, world')
238+
result = (cstring(''), cstring(''), cstring('hello, world'))
239+
assert target.rpartition(cstring(': ')) == result
240+
241+
230242
def test_startswith():
231243
target = cstring('hello, world')
232244
assert target.startswith('hello,') is True

0 commit comments

Comments
 (0)