Commit 0d2a3b1c authored by Kevin Modzelewski's avatar Kevin Modzelewski

Use CPython's implementation of str_rsplit

The organization is kind of hacky since we have to copy str_rsplit
into stringobject.c so it can be use stringlib, but we want to reference
it from str.cpp.
parent e3ae2963
......@@ -3,11 +3,17 @@
#include "Python.h"
#include "stringlib/stringdefs.h"
#include "stringlib/string_format.h"
#include "stringlib/fastsearch.h"
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/split.h"
#define _Py_InsertThousandsGrouping _PyString_InsertThousandsGrouping
#include "stringlib/localeutil.h"
#include "stringlib/string_format.h"
// do_string_format needs to be declared as a static function, since it's used by both stringobject.c
// and unicodeobject.c. We want to access it from str.cpp, though, so just use this little forwarding
// function.
......@@ -16,3 +22,30 @@
PyObject * _do_string_format(PyObject *self, PyObject *args, PyObject *kwargs) {
return do_string_format(self, args, kwargs);
}
PyObject* string_rsplit(PyStringObject* self, PyObject* args) {
Py_ssize_t len = PyString_GET_SIZE(self), n;
Py_ssize_t maxsplit = -1;
const char* s = PyString_AS_STRING(self), *sub;
PyObject* subobj = Py_None;
if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
return NULL;
if (maxsplit < 0)
maxsplit = PY_SSIZE_T_MAX;
if (subobj == Py_None)
return stringlib_rsplit_whitespace((PyObject*)self, s, len, maxsplit);
if (PyString_Check(subobj)) {
sub = PyString_AS_STRING(subobj);
n = PyString_GET_SIZE(subobj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(subobj))
return PyUnicode_RSplit((PyObject*)self, subobj, maxsplit);
#endif
else if (PyObject_AsCharBuffer(subobj, &sub, &n))
return NULL;
return stringlib_rsplit((PyObject*)self, s, len, sub, n, maxsplit);
}
......@@ -39,10 +39,6 @@ extern "C" int PyList_Append(PyObject* op, PyObject* newitem) noexcept {
return 0;
}
extern "C" int PyList_Reverse(PyObject* v) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject** PyList_Items(PyObject* op) noexcept {
RELEASE_ASSERT(PyList_Check(op), "");
......@@ -469,6 +465,21 @@ Box* listReverse(BoxedList* self) {
return None;
}
extern "C" int PyList_Reverse(PyObject* v) noexcept {
if (v == NULL || !PyList_Check(v)) {
PyErr_BadInternalCall();
return -1;
}
try {
listReverse(static_cast<BoxedList*>(v));
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
}
return 0;
}
void listSort(BoxedList* self, Box* cmp, Box* key, Box* reverse) {
LOCK_REGION(self->lock.asWrite());
assert(self->cls == list_cls);
......
......@@ -23,6 +23,7 @@
#include "Python.h"
#include "capi/types.h"
#include "core/common.h"
#include "core/types.h"
#include "core/util.h"
......@@ -33,6 +34,8 @@
#include "runtime/types.h"
#include "runtime/util.h"
extern "C" PyObject* string_rsplit(PyStringObject* self, PyObject* args) noexcept;
namespace pyston {
BoxedString::BoxedString(const char* s, size_t n) : s(s, n) {
......@@ -1636,14 +1639,6 @@ Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
}
}
Box* strRsplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
// TODO: implement this for real
// for now, just forward rsplit() to split() in the cases they have to return the same value
assert(isSubclass(_max_split->cls, int_cls));
RELEASE_ASSERT(_max_split->n <= 0, "");
return strSplit(self, sep, _max_split);
}
Box* strStrip(BoxedString* self, Box* chars) {
assert(self->cls == str_cls);
......@@ -2236,6 +2231,10 @@ void strDestructor(Box* b) {
self->s.~basic_string();
}
static PyMethodDef string_methods[] = {
{ "rsplit", (PyCFunction)string_rsplit, METH_VARARGS, NULL },
};
void setupStr() {
str_cls->simple_destructor = strDestructor;
str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
......@@ -2329,8 +2328,10 @@ void setupStr() {
str_cls->giveAttr(
"split", new BoxedFunction(boxRTFunction((void*)strSplit, LIST, 3, 2, false, false), { None, boxInt(-1) }));
str_cls->giveAttr(
"rsplit", new BoxedFunction(boxRTFunction((void*)strRsplit, LIST, 3, 2, false, false), { None, boxInt(-1) }));
for (auto& md : string_methods) {
str_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, str_cls));
}
CLFunction* count = boxRTFunction((void*)strCount2Unboxed, INT, 2);
addRTFunction(count, (void*)strCount2, BOXED_INT);
......
......@@ -15,6 +15,8 @@ print " test ".rsplit()
print " test ".rsplit(' ')
print " test ".rsplit(None)
print "1<>2<>3".rsplit('<>')
print "1<>2<>3".rsplit('<>', 1)
print "1<>2<>3".split('<>', 1)
print map(bool, ["hello", "", "world"])
......
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