Commit 3dc94a15 authored by Marius Wachtler's avatar Marius Wachtler

str: use cpythons [r]partition

it support non str separators
fixes #1297
parent ae075362
......@@ -10,7 +10,11 @@
#define STRINGLIB_CHAR char
#define STRINGLIB_TYPE_NAME "string"
#define STRINGLIB_PARSE_CODE "S"
#define STRINGLIB_EMPTY nullstring
// Pyston change:
// #define STRINGLIB_EMPTY nullstring
extern PyObject* EmptyString;
#define STRINGLIB_EMPTY EmptyString
#define STRINGLIB_ISSPACE Py_ISSPACE
#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
#define STRINGLIB_ISDECIMAL(x) ((x >= '0') && (x <= '9'))
......
......@@ -9,6 +9,7 @@
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/partition.h"
#include "stringlib/split.h"
#define _Py_InsertThousandsGrouping _PyString_InsertThousandsGrouping
......@@ -1014,3 +1015,52 @@ PyObject* string_repeat(register PyStringObject *a, register Py_ssize_t n)
}
return (PyObject *) op;
}
PyObject *
string_partition(PyStringObject *self, PyObject *sep_obj)
{
const char *sep;
Py_ssize_t sep_len;
if (PyString_Check(sep_obj)) {
sep = PyString_AS_STRING(sep_obj);
sep_len = PyString_GET_SIZE(sep_obj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(sep_obj))
return PyUnicode_Partition((PyObject *) self, sep_obj);
#endif
else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
return NULL;
return stringlib_partition(
(PyObject*) self,
PyString_AS_STRING(self), PyString_GET_SIZE(self),
sep_obj, sep, sep_len
);
}
PyObject *
string_rpartition(PyStringObject *self, PyObject *sep_obj)
{
const char *sep;
Py_ssize_t sep_len;
if (PyString_Check(sep_obj)) {
sep = PyString_AS_STRING(sep_obj);
sep_len = PyString_GET_SIZE(sep_obj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(sep_obj))
return PyUnicode_RPartition((PyObject *) self, sep_obj);
#endif
else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
return NULL;
return stringlib_rpartition(
(PyObject*) self,
PyString_AS_STRING(self), PyString_GET_SIZE(self),
sep_obj, sep, sep_len
);
}
......@@ -42,6 +42,8 @@ extern "C" PyObject* string_find(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_index(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_rindex(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_rfind(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_partition(PyStringObject* self, PyObject* sep_obj) noexcept;
extern "C" PyObject* string_rpartition(PyStringObject* self, PyObject* sep_obj) noexcept;
extern "C" PyObject* string_repeat(PyStringObject* a, Py_ssize_t n) noexcept;
extern "C" PyObject* string_replace(PyStringObject* self, PyObject* args) noexcept;
extern "C" PyObject* string_splitlines(PyStringObject* self, PyObject* args) noexcept;
......@@ -1892,38 +1894,7 @@ extern "C" PyObject* _PyString_Join(PyObject* sep, PyObject* x) noexcept {
return string_join((PyStringObject*)sep, x);
}
Box* strPartition(BoxedString* self, BoxedString* sep) {
RELEASE_ASSERT(PyString_Check(self), "");
RELEASE_ASSERT(PyString_Check(sep), "");
size_t found_idx;
if (sep->size() == 1)
found_idx = self->s().find(sep->s()[0]);
else
found_idx = self->s().find(sep->s());
if (found_idx == std::string::npos)
return BoxedTuple::create({ self, EmptyString, EmptyString });
return BoxedTuple::create({ autoDecref(boxString(llvm::StringRef(self->data(), found_idx))),
autoDecref(boxString(llvm::StringRef(self->data() + found_idx, sep->size()))),
autoDecref(boxString(llvm::StringRef(self->data() + found_idx + sep->size(),
self->size() - found_idx - sep->size()))) });
}
Box* strRpartition(BoxedString* self, BoxedString* sep) {
RELEASE_ASSERT(PyString_Check(self), "");
RELEASE_ASSERT(PyString_Check(sep), "");
size_t found_idx = self->s().rfind(sep->s());
if (found_idx == std::string::npos)
return BoxedTuple::create({ EmptyString, EmptyString, self });
return BoxedTuple::create({ autoDecref(boxString(llvm::StringRef(self->data(), found_idx))),
autoDecref(boxString(llvm::StringRef(self->data() + found_idx, sep->size()))),
autoDecref(boxString(llvm::StringRef(self->data() + found_idx + sep->size(),
self->size() - found_idx - sep->size()))) });
}
extern "C" PyObject* _do_string_format(PyObject* self, PyObject* args, PyObject* kwargs);
......@@ -2767,6 +2738,8 @@ static PyMethodDef string_methods[] = {
{ "rsplit", (PyCFunction)string_rsplit, METH_VARARGS, NULL },
{ "find", (PyCFunction)string_find, METH_VARARGS, NULL },
{ "index", (PyCFunction)string_index, METH_VARARGS, NULL },
{ "partition", (PyCFunction)string_partition, METH_O, NULL },
{ "rpartition", (PyCFunction)string_rpartition, METH_O, NULL },
{ "rindex", (PyCFunction)string_rindex, METH_VARARGS, NULL },
{ "rfind", (PyCFunction)string_rfind, METH_VARARGS, NULL },
{ "expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS, NULL },
......@@ -2841,9 +2814,6 @@ void setupStr() {
str_cls->giveAttr("endswith", new BoxedFunction(FunctionMetadata::create((void*)strEndswith, BOXED_BOOL, 4, 0, 0),
{ NULL, NULL }));
str_cls->giveAttr("partition", new BoxedFunction(FunctionMetadata::create((void*)strPartition, UNKNOWN, 2)));
str_cls->giveAttr("rpartition", new BoxedFunction(FunctionMetadata::create((void*)strRpartition, UNKNOWN, 2)));
str_cls->giveAttr("format", new BoxedFunction(FunctionMetadata::create((void*)strFormat, UNKNOWN, 1, true, true)));
str_cls->giveAttr("__add__", new BoxedFunction(FunctionMetadata::create((void*)strAdd<CXX>, UNKNOWN, 2)));
......
......@@ -94,6 +94,7 @@ for i in xrange(-10, 10):
print "hello world".partition("hi")
print "hello world".partition("hello")
print "hello world".partition("o")
print "hello world".partition(u"o")
print "hello world"[False:True:True]
......
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