153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* stringlib: partition implementation */
253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#ifndef STRINGLIB_PARTITION_H
453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#define STRINGLIB_PARTITION_H
553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#ifndef STRINGLIB_FASTSEARCH_H
753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#error must include "stringlib/fastsearch.h" before including this module
853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#endif
953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
1053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPy_LOCAL_INLINE(PyObject*)
1153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstringlib_partition(PyObject* str_obj,
1253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    const STRINGLIB_CHAR* str, Py_ssize_t str_len,
1353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    PyObject* sep_obj,
1453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
1553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
1653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject* out;
1753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t pos;
1853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
1953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (sep_len == 0) {
2053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_SetString(PyExc_ValueError, "empty separator");
2153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
2253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
2353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
2453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    out = PyTuple_New(3);
2553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!out)
2653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
2753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
2853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_SEARCH);
2953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
3053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (pos < 0) {
3153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#if STRINGLIB_MUTABLE
3253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, str_len));
3353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
3453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(NULL, 0));
3553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#else
3653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_INCREF(str_obj);
3753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj);
3853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_INCREF(STRINGLIB_EMPTY);
3953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
4053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_INCREF(STRINGLIB_EMPTY);
4153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 2, (PyObject*) STRINGLIB_EMPTY);
4253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#endif
4353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return out;
4453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
4553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
4653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
4753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_INCREF(sep_obj);
4853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyTuple_SET_ITEM(out, 1, sep_obj);
4953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    pos += sep_len;
5053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
5153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
5253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (PyErr_Occurred()) {
5353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_DECREF(out);
5453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
5553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
5653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
5753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return out;
5853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
5953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
6053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPy_LOCAL_INLINE(PyObject*)
6153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstringlib_rpartition(PyObject* str_obj,
6253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                     const STRINGLIB_CHAR* str, Py_ssize_t str_len,
6353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                     PyObject* sep_obj,
6453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                     const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
6553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
6653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject* out;
6753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t pos;
6853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
6953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (sep_len == 0) {
7053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_SetString(PyExc_ValueError, "empty separator");
7153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
7253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
7353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
7453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    out = PyTuple_New(3);
7553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!out)
7653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
7753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
7853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_RSEARCH);
7953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
8053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (pos < 0) {
8153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#if STRINGLIB_MUTABLE
8253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(NULL, 0));
8353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
8453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str, str_len));
8553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#else
8653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_INCREF(STRINGLIB_EMPTY);
8753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY);
8853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_INCREF(STRINGLIB_EMPTY);
8953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
9053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_INCREF(str_obj);
9153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
9253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#endif
9353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return out;
9453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
9553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
9653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
9753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_INCREF(sep_obj);
9853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyTuple_SET_ITEM(out, 1, sep_obj);
9953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    pos += sep_len;
10053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
10153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
10253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (PyErr_Occurred()) {
10353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_DECREF(out);
10453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
10553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
10653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
10753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return out;
10853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
10953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
11053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#endif
111