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 @@ ...@@ -3,11 +3,17 @@
#include "Python.h" #include "Python.h"
#include "stringlib/stringdefs.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 #define _Py_InsertThousandsGrouping _PyString_InsertThousandsGrouping
#include "stringlib/localeutil.h" #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 // 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 // and unicodeobject.c. We want to access it from str.cpp, though, so just use this little forwarding
// function. // function.
...@@ -16,3 +22,30 @@ ...@@ -16,3 +22,30 @@
PyObject * _do_string_format(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _do_string_format(PyObject *self, PyObject *args, PyObject *kwargs) {
return do_string_format(self, args, 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 { ...@@ -39,10 +39,6 @@ extern "C" int PyList_Append(PyObject* op, PyObject* newitem) noexcept {
return 0; return 0;
} }
extern "C" int PyList_Reverse(PyObject* v) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject** PyList_Items(PyObject* op) noexcept { extern "C" PyObject** PyList_Items(PyObject* op) noexcept {
RELEASE_ASSERT(PyList_Check(op), ""); RELEASE_ASSERT(PyList_Check(op), "");
...@@ -469,6 +465,21 @@ Box* listReverse(BoxedList* self) { ...@@ -469,6 +465,21 @@ Box* listReverse(BoxedList* self) {
return None; 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) { void listSort(BoxedList* self, Box* cmp, Box* key, Box* reverse) {
LOCK_REGION(self->lock.asWrite()); LOCK_REGION(self->lock.asWrite());
assert(self->cls == list_cls); assert(self->cls == list_cls);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "Python.h" #include "Python.h"
#include "capi/types.h"
#include "core/common.h" #include "core/common.h"
#include "core/types.h" #include "core/types.h"
#include "core/util.h" #include "core/util.h"
...@@ -33,6 +34,8 @@ ...@@ -33,6 +34,8 @@
#include "runtime/types.h" #include "runtime/types.h"
#include "runtime/util.h" #include "runtime/util.h"
extern "C" PyObject* string_rsplit(PyStringObject* self, PyObject* args) noexcept;
namespace pyston { namespace pyston {
BoxedString::BoxedString(const char* s, size_t n) : s(s, n) { BoxedString::BoxedString(const char* s, size_t n) : s(s, n) {
...@@ -1636,14 +1639,6 @@ Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) { ...@@ -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) { Box* strStrip(BoxedString* self, Box* chars) {
assert(self->cls == str_cls); assert(self->cls == str_cls);
...@@ -2236,6 +2231,10 @@ void strDestructor(Box* b) { ...@@ -2236,6 +2231,10 @@ void strDestructor(Box* b) {
self->s.~basic_string(); self->s.~basic_string();
} }
static PyMethodDef string_methods[] = {
{ "rsplit", (PyCFunction)string_rsplit, METH_VARARGS, NULL },
};
void setupStr() { void setupStr() {
str_cls->simple_destructor = strDestructor; str_cls->simple_destructor = strDestructor;
str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; str_cls->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
...@@ -2329,8 +2328,10 @@ void setupStr() { ...@@ -2329,8 +2328,10 @@ void setupStr() {
str_cls->giveAttr( str_cls->giveAttr(
"split", new BoxedFunction(boxRTFunction((void*)strSplit, LIST, 3, 2, false, false), { None, boxInt(-1) })); "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); CLFunction* count = boxRTFunction((void*)strCount2Unboxed, INT, 2);
addRTFunction(count, (void*)strCount2, BOXED_INT); addRTFunction(count, (void*)strCount2, BOXED_INT);
......
...@@ -15,6 +15,8 @@ print " test ".rsplit() ...@@ -15,6 +15,8 @@ print " test ".rsplit()
print " test ".rsplit(' ') print " test ".rsplit(' ')
print " test ".rsplit(None) print " test ".rsplit(None)
print "1<>2<>3".rsplit('<>') print "1<>2<>3".rsplit('<>')
print "1<>2<>3".rsplit('<>', 1)
print "1<>2<>3".split('<>', 1)
print map(bool, ["hello", "", "world"]) 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