Commit c1085d8c authored by Kevin Modzelewski's avatar Kevin Modzelewski

Switch to CPython's str.find and str.rfind

parent d0ebb755
......@@ -49,3 +49,56 @@ PyObject* string_rsplit(PyStringObject* self, PyObject* args) {
return stringlib_rsplit((PyObject*)self, s, len, sub, n, maxsplit);
}
Py_LOCAL_INLINE(Py_ssize_t)
string_find_internal(PyStringObject *self, PyObject *args, int dir)
{
PyObject *subobj;
const char *sub;
Py_ssize_t sub_len;
Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
if (!stringlib_parse_args_finds("find/rfind/index/rindex",
args, &subobj, &start, &end))
return -2;
if (PyString_Check(subobj)) {
sub = PyString_AS_STRING(subobj);
sub_len = PyString_GET_SIZE(subobj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(subobj))
return PyUnicode_Find(
(PyObject *)self, subobj, start, end, dir);
#endif
else if (PyObject_AsCharBuffer(subobj, &sub, &sub_len))
/* XXX - the "expected a character buffer object" is pretty
confusing for a non-expert. remap to something else ? */
return -2;
if (dir > 0)
return stringlib_find_slice(
PyString_AS_STRING(self), PyString_GET_SIZE(self),
sub, sub_len, start, end);
else
return stringlib_rfind_slice(
PyString_AS_STRING(self), PyString_GET_SIZE(self),
sub, sub_len, start, end);
}
PyObject *
string_rfind(PyStringObject *self, PyObject *args)
{
Py_ssize_t result = string_find_internal(self, args, -1);
if (result == -2)
return NULL;
return PyInt_FromSsize_t(result);
}
PyObject *
string_find(PyStringObject *self, PyObject *args)
{
Py_ssize_t result = string_find_internal(self, args, +1);
if (result == -2)
return NULL;
return PyInt_FromSsize_t(result);
}
......@@ -35,6 +35,8 @@
#include "runtime/util.h"
extern "C" PyObject* string_rsplit(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_find(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_rfind(PyStringObject* self, PyObject* args) noexcept;
namespace pyston {
......@@ -1917,49 +1919,6 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
return result;
}
Box* strFind(BoxedString* self, Box* elt, Box* _start) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'find' requires a 'str' object but received a '%s'", getTypeName(self));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
if (_start->cls != int_cls) {
raiseExcHelper(TypeError, "'start' must be an int for now");
// Real error message:
// raiseExcHelper(TypeError, "slice indices must be integers or None or have an __index__ method");
}
int64_t start = static_cast<BoxedInt*>(_start)->n;
if (start < 0) {
start += self->s.size();
start = std::max(0L, start);
}
BoxedString* sub = static_cast<BoxedString*>(elt);
size_t r = self->s.find(sub->s, start);
if (r == std::string::npos)
return boxInt(-1);
return boxInt(r);
}
Box* strRfind(BoxedString* self, Box* elt) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'rfind' requires a 'str' object but received a '%s'", getTypeName(self));
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* sub = static_cast<BoxedString*>(elt);
size_t r = self->s.rfind(sub->s);
if (r == std::string::npos)
return boxInt(-1);
return boxInt(r);
}
extern "C" Box* strGetitem(BoxedString* self, Box* slice) {
assert(self->cls == str_cls);
......@@ -2233,6 +2192,8 @@ void strDestructor(Box* b) {
static PyMethodDef string_methods[] = {
{ "rsplit", (PyCFunction)string_rsplit, METH_VARARGS, NULL },
{ "find", (PyCFunction)string_find, METH_VARARGS, NULL },
{ "rfind", (PyCFunction)string_rfind, METH_VARARGS, NULL },
};
void setupStr() {
......@@ -2288,10 +2249,6 @@ void setupStr() {
str_cls->giveAttr("endswith",
new BoxedFunction(boxRTFunction((void*)strEndswith, BOXED_BOOL, 4, 2, 0, 0), { NULL, NULL }));
str_cls->giveAttr("find",
new BoxedFunction(boxRTFunction((void*)strFind, BOXED_INT, 3, 1, false, false), { boxInt(0) }));
str_cls->giveAttr("rfind", new BoxedFunction(boxRTFunction((void*)strRfind, BOXED_INT, 2)));
str_cls->giveAttr("partition", new BoxedFunction(boxRTFunction((void*)strPartition, UNKNOWN, 2)));
str_cls->giveAttr("format", new BoxedFunction(boxRTFunction((void*)strFormat, UNKNOWN, 1, 0, true, true)));
......
......@@ -80,7 +80,8 @@ print "hello world".translate(translation_map, "llo")
print "hello world".translate(None, "llo")
for i in xrange(-10, 10):
print i, "aaaaa".find("a", i)
print i, "aaaaa".find("a", i), "aaaa".find("a", 2, i)
print i, "aaaaa".rfind("a", i), "aaaa".rfind("a", 2, i)
print "hello world".partition("hi")
print "hello world".partition("hello")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment