blob: d3490b902fbf868b1395d654264b873d7ac8a7a7 [file] [log] [blame]
Fredrik Lundh58b5e842006-05-26 19:24:53 +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
Fredrik Lundhc2d29c52006-05-27 14:58:20 +000010Py_LOCAL_INLINE(Py_ssize_t)
Fredrik Lundh58b5e842006-05-26 19:24:53 +000011stringlib_find(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
Fredrik Lundhe6e43c82006-05-26 19:48:07 +000012 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
13 Py_ssize_t offset)
Fredrik Lundh58b5e842006-05-26 19:24:53 +000014{
Fredrik Lundhe6e43c82006-05-26 19:48:07 +000015 Py_ssize_t pos;
Fredrik Lundh58b5e842006-05-26 19:24:53 +000016
Fredrik Lundh93eff6f2006-05-30 17:11:48 +000017 if (sub_len == 0) {
18 if (str_len < 0)
19 return -1;
Fredrik Lundhe6e43c82006-05-26 19:48:07 +000020 return offset;
Fredrik Lundh93eff6f2006-05-30 17:11:48 +000021 }
Fredrik Lundhe6e43c82006-05-26 19:48:07 +000022
23 pos = fastsearch(str, str_len, sub, sub_len, FAST_SEARCH);
24
25 if (pos >= 0)
26 pos += offset;
27
28 return pos;
Fredrik Lundh58b5e842006-05-26 19:24:53 +000029}
30
Fredrik Lundhc2d29c52006-05-27 14:58:20 +000031Py_LOCAL_INLINE(Py_ssize_t)
Fredrik Lundh58b5e842006-05-26 19:24:53 +000032stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
Fredrik Lundhe6e43c82006-05-26 19:48:07 +000033 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
34 Py_ssize_t offset)
Fredrik Lundh58b5e842006-05-26 19:24:53 +000035{
Fredrik Lundh58b5e842006-05-26 19:24:53 +000036 /* XXX - create reversefastsearch helper! */
Fredrik Lundh93eff6f2006-05-30 17:11:48 +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;
Fredrik Lundh58b5e842006-05-26 19:24:53 +000043 for (j = str_len - sub_len; j >= 0; --j)
44 if (STRINGLIB_CMP(str+j, sub, sub_len) == 0) {
Fredrik Lundhe6e43c82006-05-26 19:48:07 +000045 pos = j + offset;
Fredrik Lundh58b5e842006-05-26 19:24:53 +000046 break;
47 }
Fredrik Lundh93eff6f2006-05-30 17:11:48 +000048 return pos;
Fredrik Lundh58b5e842006-05-26 19:24:53 +000049 }
Fredrik Lundh58b5e842006-05-26 19:24:53 +000050}
51
Fredrik Lundhc2d29c52006-05-27 14:58:20 +000052Py_LOCAL_INLINE(Py_ssize_t)
Fredrik Lundh60d8b182006-05-27 15:20:22 +000053stringlib_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)
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000056{
Fredrik Lundh60d8b182006-05-27 15:20:22 +000057 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
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000068 return stringlib_find(
Fredrik Lundh60d8b182006-05-27 15:20:22 +000069 str + start, end - start,
70 sub, sub_len, start
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000071 );
72}
73
Fredrik Lundh60d8b182006-05-27 15:20:22 +000074Py_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
93#ifdef STRINGLIB_STR
94
Fredrik Lundhc2d29c52006-05-27 14:58:20 +000095Py_LOCAL_INLINE(int)
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000096stringlib_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
Fredrik Lundh60d8b182006-05-27 15:20:22 +0000104#endif /* STRINGLIB_STR */
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +0000105
Facundo Batista57d56692007-11-16 18:04:14 +0000106/*
107This function is a helper for the "find" family (find, rfind, index,
108rindex) of unicodeobject.c file, because they all have the same
109behaviour for the arguments.
110
111It does not touch the variables received until it knows everything
112is ok.
113
114Note that we receive a pointer to the pointer of the substring object,
115so when we create that object in this function we don't DECREF it,
116because it continues living in the caller functions (those functions,
117after finishing using the substring, must DECREF it).
118*/
119
Facundo Batista292a0692007-11-16 18:41:24 +0000120Py_LOCAL_INLINE(int)
Facundo Batista57d56692007-11-16 18:04:14 +0000121_ParseTupleFinds (PyObject *args, PyObject **substring,
122 Py_ssize_t *start, Py_ssize_t *end) {
123 PyObject *tmp_substring;
124 Py_ssize_t tmp_start = 0;
125 Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
126 PyObject *obj_start=Py_None, *obj_end=Py_None;
127
128 if (!PyArg_ParseTuple(args, "O|OO:find", &tmp_substring,
129 &obj_start, &obj_end))
130 return 0;
131
132 /* To support None in "start" and "end" arguments, meaning
133 the same as if they were not passed.
134 */
135 if (obj_start != Py_None)
136 if (!_PyEval_SliceIndex(obj_start, &tmp_start))
137 return 0;
138 if (obj_end != Py_None)
139 if (!_PyEval_SliceIndex(obj_end, &tmp_end))
140 return 0;
141
142 tmp_substring = PyUnicode_FromObject(tmp_substring);
143 if (!tmp_substring)
144 return 0;
145
146 *start = tmp_start;
147 *end = tmp_end;
148 *substring = tmp_substring;
149 return 1;
150}
151
152
Fredrik Lundh60d8b182006-05-27 15:20:22 +0000153#endif /* STRINGLIB_FIND_H */
Fredrik Lundh58b5e842006-05-26 19:24:53 +0000154
155/*
156Local variables:
157c-basic-offset: 4
158indent-tabs-mode: nil
159End:
160*/