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