blob: bcc217697b2e9cb6066ac28b770da892f3e623cb [file] [log] [blame]
Thomas Wouters477c8d52006-05-27 19:21:47 +00001/* stringlib: partition implementation */
2
Thomas Wouters477c8d52006-05-27 19:21:47 +00003#ifndef STRINGLIB_FASTSEARCH_H
Victor Stinnerf363d0a2020-06-24 00:10:40 +02004# error must include "stringlib/fastsearch.h" before including this module
Thomas Wouters477c8d52006-05-27 19:21:47 +00005#endif
6
Victor Stinnerf363d0a2020-06-24 00:10:40 +02007#if !STRINGLIB_MUTABLE && !defined(STRINGLIB_GET_EMPTY)
8# error "STRINGLIB_GET_EMPTY must be defined if STRINGLIB_MUTABLE is zero"
9#endif
10
11
Thomas Wouters477c8d52006-05-27 19:21:47 +000012Py_LOCAL_INLINE(PyObject*)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020013STRINGLIB(partition)(PyObject* str_obj,
Antoine Pitrouf2c54842010-01-13 08:07:53 +000014 const STRINGLIB_CHAR* str, Py_ssize_t str_len,
15 PyObject* sep_obj,
16 const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +000017{
18 PyObject* out;
19 Py_ssize_t pos;
20
21 if (sep_len == 0) {
22 PyErr_SetString(PyExc_ValueError, "empty separator");
Antoine Pitrouf2c54842010-01-13 08:07:53 +000023 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000024 }
25
26 out = PyTuple_New(3);
27 if (!out)
Antoine Pitrouf2c54842010-01-13 08:07:53 +000028 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000029
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020030 pos = FASTSEARCH(str, str_len, sep, sep_len, -1, FAST_SEARCH);
Thomas Wouters477c8d52006-05-27 19:21:47 +000031
32 if (pos < 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +000033#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));
Victor Stinnercc64eb52013-10-29 03:15:37 +010037
38 if (PyErr_Occurred()) {
39 Py_DECREF(out);
40 return NULL;
41 }
Antoine Pitrouf2c54842010-01-13 08:07:53 +000042#else
43 Py_INCREF(str_obj);
44 PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj);
Victor Stinnerc41eed12020-06-23 15:54:35 +020045 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);
Antoine Pitrouf2c54842010-01-13 08:07:53 +000051#endif
52 return out;
Thomas Wouters477c8d52006-05-27 19:21:47 +000053 }
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()) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +000062 Py_DECREF(out);
63 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000064 }
65
66 return out;
67}
68
69Py_LOCAL_INLINE(PyObject*)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020070STRINGLIB(rpartition)(PyObject* str_obj,
Antoine Pitrouf2c54842010-01-13 08:07:53 +000071 const STRINGLIB_CHAR* str, Py_ssize_t str_len,
72 PyObject* sep_obj,
73 const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +000074{
75 PyObject* out;
Antoine Pitrouda2ecaf2010-01-02 21:40:36 +000076 Py_ssize_t pos;
Thomas Wouters477c8d52006-05-27 19:21:47 +000077
78 if (sep_len == 0) {
79 PyErr_SetString(PyExc_ValueError, "empty separator");
Antoine Pitrouf2c54842010-01-13 08:07:53 +000080 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000081 }
82
83 out = PyTuple_New(3);
84 if (!out)
Antoine Pitrouf2c54842010-01-13 08:07:53 +000085 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +000086
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020087 pos = FASTSEARCH(str, str_len, sep, sep_len, -1, FAST_RSEARCH);
Thomas Wouters477c8d52006-05-27 19:21:47 +000088
89 if (pos < 0) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +000090#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));
Victor Stinnercc64eb52013-10-29 03:15:37 +010094
95 if (PyErr_Occurred()) {
96 Py_DECREF(out);
97 return NULL;
98 }
Antoine Pitrouf2c54842010-01-13 08:07:53 +000099#else
Victor Stinnerc41eed12020-06-23 15:54:35 +0200100 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);
Antoine Pitrouf2c54842010-01-13 08:07:53 +0000106 Py_INCREF(str_obj);
107 PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
108#endif
109 return out;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000110 }
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()) {
Antoine Pitrouf2c54842010-01-13 08:07:53 +0000119 Py_DECREF(out);
120 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000121 }
122
123 return out;
124}
125