blob: 9e0d299845259ce373008c16b50d0406ec3b847f [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
Christian Heimes7d4c3172008-08-22 19:47:25 +000093#if defined(STRINGLIB_STR) && !defined(FROM_BYTEARRAY)
Fredrik Lundh60d8b182006-05-27 15:20:22 +000094
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 Batista6f7e6fb2007-11-16 19:16:15 +0000106#ifdef FROM_UNICODE
107
Facundo Batista57d56692007-11-16 18:04:14 +0000108/*
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
Facundo Batista292a0692007-11-16 18:41:24 +0000122Py_LOCAL_INLINE(int)
Facundo Batista57d56692007-11-16 18:04:14 +0000123_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
Facundo Batista6f7e6fb2007-11-16 19:16:15 +0000154#endif /* FROM_UNICODE */
Facundo Batista57d56692007-11-16 18:04:14 +0000155
Fredrik Lundh60d8b182006-05-27 15:20:22 +0000156#endif /* STRINGLIB_FIND_H */
Fredrik Lundh58b5e842006-05-26 19:24:53 +0000157
158/*
159Local variables:
160c-basic-offset: 4
161indent-tabs-mode: nil
162End:
163*/