blob: fbe99c75ae20e474bb9710fccf92176f345a3df1 [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
Amaury Forgeot d'Arcfc5ea392008-09-26 22:34:08 +000017 if (str_len < 0)
18 return -1;
19 if (sub_len == 0)
Fredrik Lundhe6e43c82006-05-26 19:48:07 +000020 return offset;
21
22 pos = fastsearch(str, str_len, sub, sub_len, FAST_SEARCH);
23
24 if (pos >= 0)
25 pos += offset;
26
27 return pos;
Fredrik Lundh58b5e842006-05-26 19:24:53 +000028}
29
Fredrik Lundhc2d29c52006-05-27 14:58:20 +000030Py_LOCAL_INLINE(Py_ssize_t)
Fredrik Lundh58b5e842006-05-26 19:24:53 +000031stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
Fredrik Lundhe6e43c82006-05-26 19:48:07 +000032 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
33 Py_ssize_t offset)
Fredrik Lundh58b5e842006-05-26 19:24:53 +000034{
Fredrik Lundh58b5e842006-05-26 19:24:53 +000035 /* XXX - create reversefastsearch helper! */
Fredrik Lundh93eff6f2006-05-30 17:11:48 +000036 if (sub_len == 0) {
37 if (str_len < 0)
38 return -1;
39 return str_len + offset;
40 } else {
41 Py_ssize_t j, pos = -1;
Fredrik Lundh58b5e842006-05-26 19:24:53 +000042 for (j = str_len - sub_len; j >= 0; --j)
43 if (STRINGLIB_CMP(str+j, sub, sub_len) == 0) {
Fredrik Lundhe6e43c82006-05-26 19:48:07 +000044 pos = j + offset;
Fredrik Lundh58b5e842006-05-26 19:24:53 +000045 break;
46 }
Fredrik Lundh93eff6f2006-05-30 17:11:48 +000047 return pos;
Fredrik Lundh58b5e842006-05-26 19:24:53 +000048 }
Fredrik Lundh58b5e842006-05-26 19:24:53 +000049}
50
Fredrik Lundhc2d29c52006-05-27 14:58:20 +000051Py_LOCAL_INLINE(Py_ssize_t)
Fredrik Lundh60d8b182006-05-27 15:20:22 +000052stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
53 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
54 Py_ssize_t start, Py_ssize_t end)
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000055{
Fredrik Lundh60d8b182006-05-27 15:20:22 +000056 if (start < 0)
57 start += str_len;
58 if (start < 0)
59 start = 0;
60 if (end > str_len)
61 end = str_len;
62 if (end < 0)
63 end += str_len;
64 if (end < 0)
65 end = 0;
66
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000067 return stringlib_find(
Fredrik Lundh60d8b182006-05-27 15:20:22 +000068 str + start, end - start,
69 sub, sub_len, start
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000070 );
71}
72
Fredrik Lundh60d8b182006-05-27 15:20:22 +000073Py_LOCAL_INLINE(Py_ssize_t)
74stringlib_rfind_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
75 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
76 Py_ssize_t start, Py_ssize_t end)
77{
78 if (start < 0)
79 start += str_len;
80 if (start < 0)
81 start = 0;
82 if (end > str_len)
83 end = str_len;
84 if (end < 0)
85 end += str_len;
86 if (end < 0)
87 end = 0;
88
89 return stringlib_rfind(str + start, end - start, sub, sub_len, start);
90}
91
Christian Heimes7d4c3172008-08-22 19:47:25 +000092#if defined(STRINGLIB_STR) && !defined(FROM_BYTEARRAY)
Fredrik Lundh60d8b182006-05-27 15:20:22 +000093
Fredrik Lundhc2d29c52006-05-27 14:58:20 +000094Py_LOCAL_INLINE(int)
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000095stringlib_contains_obj(PyObject* str, PyObject* sub)
96{
97 return stringlib_find(
98 STRINGLIB_STR(str), STRINGLIB_LEN(str),
99 STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0
100 ) != -1;
101}
102
Fredrik Lundh60d8b182006-05-27 15:20:22 +0000103#endif /* STRINGLIB_STR */
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +0000104
Facundo Batista6f7e6fb2007-11-16 19:16:15 +0000105#ifdef FROM_UNICODE
106
Facundo Batista57d56692007-11-16 18:04:14 +0000107/*
108This function is a helper for the "find" family (find, rfind, index,
109rindex) of unicodeobject.c file, because they all have the same
110behaviour for the arguments.
111
112It does not touch the variables received until it knows everything
113is ok.
114
115Note that we receive a pointer to the pointer of the substring object,
116so when we create that object in this function we don't DECREF it,
117because it continues living in the caller functions (those functions,
118after finishing using the substring, must DECREF it).
119*/
120
Facundo Batista292a0692007-11-16 18:41:24 +0000121Py_LOCAL_INLINE(int)
Facundo Batista57d56692007-11-16 18:04:14 +0000122_ParseTupleFinds (PyObject *args, PyObject **substring,
123 Py_ssize_t *start, Py_ssize_t *end) {
124 PyObject *tmp_substring;
125 Py_ssize_t tmp_start = 0;
126 Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
127 PyObject *obj_start=Py_None, *obj_end=Py_None;
128
129 if (!PyArg_ParseTuple(args, "O|OO:find", &tmp_substring,
130 &obj_start, &obj_end))
131 return 0;
132
133 /* To support None in "start" and "end" arguments, meaning
134 the same as if they were not passed.
135 */
136 if (obj_start != Py_None)
137 if (!_PyEval_SliceIndex(obj_start, &tmp_start))
138 return 0;
139 if (obj_end != Py_None)
140 if (!_PyEval_SliceIndex(obj_end, &tmp_end))
141 return 0;
142
143 tmp_substring = PyUnicode_FromObject(tmp_substring);
144 if (!tmp_substring)
145 return 0;
146
147 *start = tmp_start;
148 *end = tmp_end;
149 *substring = tmp_substring;
150 return 1;
151}
152
Facundo Batista6f7e6fb2007-11-16 19:16:15 +0000153#endif /* FROM_UNICODE */
Facundo Batista57d56692007-11-16 18:04:14 +0000154
Fredrik Lundh60d8b182006-05-27 15:20:22 +0000155#endif /* STRINGLIB_FIND_H */
Fredrik Lundh58b5e842006-05-26 19:24:53 +0000156
157/*
158Local variables:
159c-basic-offset: 4
160indent-tabs-mode: nil
161End:
162*/