• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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*)
STRINGLIB(partition)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*)
STRINGLIB(rpartition)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