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