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 | |
12 | Py_LOCAL_INLINE(PyObject*) |
13 | STRINGLIB(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 | |
69 | Py_LOCAL_INLINE(PyObject*) |
70 | STRINGLIB(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 | |