blob: 46337e1773eeb59978abeac6da2fbde72d140d55 [file] [log] [blame]
Thomas Wouters477c8d52006-05-27 19:21:47 +00001/* stringlib: find/index implementation */
2
3#ifndef STRINGLIB_FIND_H
4#define STRINGLIB_FIND_H
5
6#ifndef STRINGLIB_FASTSEARCH_H
7#error must include "stringlib/fastsearch.h" before including this module
8#endif
9
10Py_LOCAL_INLINE(Py_ssize_t)
11stringlib_find(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
12 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
13 Py_ssize_t offset)
14{
15 Py_ssize_t pos;
16
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000017 if (sub_len == 0) {
18 if (str_len < 0)
19 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000020 return offset;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000021 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000022
23 pos = fastsearch(str, str_len, sub, sub_len, FAST_SEARCH);
24
25 if (pos >= 0)
26 pos += offset;
27
28 return pos;
29}
30
31Py_LOCAL_INLINE(Py_ssize_t)
32stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
33 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
34 Py_ssize_t offset)
35{
Thomas Wouters477c8d52006-05-27 19:21:47 +000036 /* XXX - create reversefastsearch helper! */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000037 if (sub_len == 0) {
38 if (str_len < 0)
39 return -1;
40 return str_len + offset;
41 } else {
42 Py_ssize_t j, pos = -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +000043 for (j = str_len - sub_len; j >= 0; --j)
44 if (STRINGLIB_CMP(str+j, sub, sub_len) == 0) {
45 pos = j + offset;
46 break;
47 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000048 return pos;
Thomas Wouters477c8d52006-05-27 19:21:47 +000049 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000050}
51
52Py_LOCAL_INLINE(Py_ssize_t)
53stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
54 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
55 Py_ssize_t start, Py_ssize_t end)
56{
57 if (start < 0)
58 start += str_len;
59 if (start < 0)
60 start = 0;
61 if (end > str_len)
62 end = str_len;
63 if (end < 0)
64 end += str_len;
65 if (end < 0)
66 end = 0;
67
68 return stringlib_find(
69 str + start, end - start,
70 sub, sub_len, start
71 );
72}
73
74Py_LOCAL_INLINE(Py_ssize_t)
75stringlib_rfind_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
76 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
77 Py_ssize_t start, Py_ssize_t end)
78{
79 if (start < 0)
80 start += str_len;
81 if (start < 0)
82 start = 0;
83 if (end > str_len)
84 end = str_len;
85 if (end < 0)
86 end += str_len;
87 if (end < 0)
88 end = 0;
89
90 return stringlib_rfind(str + start, end - start, sub, sub_len, start);
91}
92
Gregory P. Smith60d241f2007-10-16 06:31:30 +000093#ifdef STRINGLIB_WANT_CONTAINS_OBJ
Thomas Wouters477c8d52006-05-27 19:21:47 +000094
95Py_LOCAL_INLINE(int)
96stringlib_contains_obj(PyObject* str, PyObject* sub)
97{
98 return stringlib_find(
99 STRINGLIB_STR(str), STRINGLIB_LEN(str),
100 STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0
101 ) != -1;
102}
103
104#endif /* STRINGLIB_STR */
105
Christian Heimes9cd17752007-11-18 19:35:23 +0000106#ifdef FROM_UNICODE
107
108/*
109This function is a helper for the "find" family (find, rfind, index,
110rindex) of unicodeobject.c file, because they all have the same
111behaviour for the arguments.
112
113It does not touch the variables received until it knows everything
114is ok.
115
116Note that we receive a pointer to the pointer of the substring object,
117so when we create that object in this function we don't DECREF it,
118because it continues living in the caller functions (those functions,
119after finishing using the substring, must DECREF it).
120*/
121
122Py_LOCAL_INLINE(int)
123_ParseTupleFinds (PyObject *args, PyObject **substring,
124 Py_ssize_t *start, Py_ssize_t *end) {
125 PyObject *tmp_substring;
126 Py_ssize_t tmp_start = 0;
127 Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
128 PyObject *obj_start=Py_None, *obj_end=Py_None;
129
130 if (!PyArg_ParseTuple(args, "O|OO:find", &tmp_substring,
131 &obj_start, &obj_end))
132 return 0;
133
134 /* To support None in "start" and "end" arguments, meaning
135 the same as if they were not passed.
136 */
137 if (obj_start != Py_None)
138 if (!_PyEval_SliceIndex(obj_start, &tmp_start))
139 return 0;
140 if (obj_end != Py_None)
141 if (!_PyEval_SliceIndex(obj_end, &tmp_end))
142 return 0;
143
144 tmp_substring = PyUnicode_FromObject(tmp_substring);
145 if (!tmp_substring)
146 return 0;
147
148 *start = tmp_start;
149 *end = tmp_end;
150 *substring = tmp_substring;
151 return 1;
152}
153
154#endif /* FROM_UNICODE */
155
Thomas Wouters477c8d52006-05-27 19:21:47 +0000156#endif /* STRINGLIB_FIND_H */
157
158/*
159Local variables:
160c-basic-offset: 4
161indent-tabs-mode: nil
162End:
163*/