1 /* stringlib: partition implementation */
2 
3 #ifndef STRINGLIB_FASTSEARCH_H
4 #error must include "stringlib/fastsearch.h" before including this module
5 #endif
6 
7 Py_LOCAL_INLINE(PyObject*)
STRINGLIB(partition)8 STRINGLIB(partition)(PyObject* str_obj,
9                     const STRINGLIB_CHAR* str, Py_ssize_t str_len,
10                     PyObject* sep_obj,
11                     const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
12 {
13     PyObject* out;
14     Py_ssize_t pos;
15 
16     if (sep_len == 0) {
17         PyErr_SetString(PyExc_ValueError, "empty separator");
18         return NULL;
19     }
20 
21     out = PyTuple_New(3);
22     if (!out)
23         return NULL;
24 
25     pos = FASTSEARCH(str, str_len, sep, sep_len, -1, FAST_SEARCH);
26 
27     if (pos < 0) {
28 #if STRINGLIB_MUTABLE
29         PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, str_len));
30         PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
31         PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(NULL, 0));
32 
33         if (PyErr_Occurred()) {
34             Py_DECREF(out);
35             return NULL;
36         }
37 #else
38         Py_INCREF(str_obj);
39         PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj);
40         Py_INCREF(STRINGLIB_EMPTY);
41         PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
42         Py_INCREF(STRINGLIB_EMPTY);
43         PyTuple_SET_ITEM(out, 2, (PyObject*) STRINGLIB_EMPTY);
44 #endif
45         return out;
46     }
47 
48     PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
49     Py_INCREF(sep_obj);
50     PyTuple_SET_ITEM(out, 1, sep_obj);
51     pos += sep_len;
52     PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
53 
54     if (PyErr_Occurred()) {
55         Py_DECREF(out);
56         return NULL;
57     }
58 
59     return out;
60 }
61 
62 Py_LOCAL_INLINE(PyObject*)
STRINGLIB(rpartition)63 STRINGLIB(rpartition)(PyObject* str_obj,
64                      const STRINGLIB_CHAR* str, Py_ssize_t str_len,
65                      PyObject* sep_obj,
66                      const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
67 {
68     PyObject* out;
69     Py_ssize_t pos;
70 
71     if (sep_len == 0) {
72         PyErr_SetString(PyExc_ValueError, "empty separator");
73         return NULL;
74     }
75 
76     out = PyTuple_New(3);
77     if (!out)
78         return NULL;
79 
80     pos = FASTSEARCH(str, str_len, sep, sep_len, -1, FAST_RSEARCH);
81 
82     if (pos < 0) {
83 #if STRINGLIB_MUTABLE
84         PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(NULL, 0));
85         PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
86         PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str, str_len));
87 
88         if (PyErr_Occurred()) {
89             Py_DECREF(out);
90             return NULL;
91         }
92 #else
93         Py_INCREF(STRINGLIB_EMPTY);
94         PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY);
95         Py_INCREF(STRINGLIB_EMPTY);
96         PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
97         Py_INCREF(str_obj);
98         PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
99 #endif
100         return out;
101     }
102 
103     PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
104     Py_INCREF(sep_obj);
105     PyTuple_SET_ITEM(out, 1, sep_obj);
106     pos += sep_len;
107     PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
108 
109     if (PyErr_Occurred()) {
110         Py_DECREF(out);
111         return NULL;
112     }
113 
114     return out;
115 }
116 
117