@@ -292,6 +292,35 @@ PyObject *cstring_index(PyObject *self, PyObject *args) {
292292 return NULL ;
293293}
294294
295+ static const char * _substr_params_rstr (struct _substr_params * params ) {
296+ const char * p = params -> end - params -> substr_len + 1 ;
297+
298+ for (;;) {
299+ p = memrchr (params -> start , * params -> substr , p - params -> start );
300+ if (!p )
301+ goto done ;
302+ if (memcmp (p , params -> substr , params -> substr_len ) == 0 )
303+ return p ;
304+ }
305+
306+ done :
307+ return NULL ;
308+ }
309+
310+ PyDoc_STRVAR (rfind__doc__ , "" );
311+ PyObject * cstring_rfind (PyObject * self , PyObject * args ) {
312+ struct _substr_params params ;
313+
314+ if (!_parse_substr_args (self , args , & params ))
315+ return NULL ;
316+
317+ const char * p = _substr_params_rstr (& params );
318+ if (!p )
319+ return PyLong_FromLong (-1 );
320+
321+ return PyLong_FromSsize_t (p - CSTRING_VALUE (self ));
322+ }
323+
295324static PySequenceMethods cstring_as_sequence = {
296325 .sq_length = cstring_len ,
297326 .sq_concat = cstring_concat ,
@@ -309,6 +338,7 @@ static PyMethodDef cstring_methods[] = {
309338 {"count" , cstring_count , METH_VARARGS , count__doc__ },
310339 {"find" , cstring_find , METH_VARARGS , find__doc__ },
311340 {"index" , cstring_index , METH_VARARGS , index__doc__ },
341+ {"rfind" , cstring_rfind , METH_VARARGS , rfind__doc__ },
312342 {0 },
313343};
314344
0 commit comments