blob: b5bace7a966c39f4a8b3f4e87668cd444fd1535f [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{
Antoine Pitrou5b7139a2010-01-02 21:12:58 +000035 Py_ssize_t pos;
36
37 if (str_len < 0)
38 return -1;
39 if (sub_len == 0)
40 return str_len + offset;
41
42 pos = fastsearch(str, str_len, sub, sub_len, FAST_RSEARCH);
43
44 if (pos >= 0)
45 pos += offset;
46
47 return pos;
Fredrik Lundh58b5e842006-05-26 19:24:53 +000048}
49
Fredrik Lundhc2d29c52006-05-27 14:58:20 +000050Py_LOCAL_INLINE(Py_ssize_t)
Fredrik Lundh60d8b182006-05-27 15:20:22 +000051stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
52 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
53 Py_ssize_t start, Py_ssize_t end)
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000054{
Fredrik Lundh60d8b182006-05-27 15:20:22 +000055 if (start < 0)
56 start += str_len;
57 if (start < 0)
58 start = 0;
59 if (end > str_len)
60 end = str_len;
61 if (end < 0)
62 end += str_len;
63 if (end < 0)
64 end = 0;
65
Antoine Pitrou5b7139a2010-01-02 21:12:58 +000066 return stringlib_find(str + start, end - start, sub, sub_len, start);
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000067}
68
Fredrik Lundh60d8b182006-05-27 15:20:22 +000069Py_LOCAL_INLINE(Py_ssize_t)
70stringlib_rfind_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
71 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
72 Py_ssize_t start, Py_ssize_t end)
73{
74 if (start < 0)
75 start += str_len;
76 if (start < 0)
77 start = 0;
78 if (end > str_len)
79 end = str_len;
80 if (end < 0)
81 end += str_len;
82 if (end < 0)
83 end = 0;
84
85 return stringlib_rfind(str + start, end - start, sub, sub_len, start);
86}
87
Christian Heimes7d4c3172008-08-22 19:47:25 +000088#if defined(STRINGLIB_STR) && !defined(FROM_BYTEARRAY)
Fredrik Lundh60d8b182006-05-27 15:20:22 +000089
Fredrik Lundhc2d29c52006-05-27 14:58:20 +000090Py_LOCAL_INLINE(int)
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +000091stringlib_contains_obj(PyObject* str, PyObject* sub)
92{
93 return stringlib_find(
94 STRINGLIB_STR(str), STRINGLIB_LEN(str),
95 STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0
96 ) != -1;
97}
98
Fredrik Lundh60d8b182006-05-27 15:20:22 +000099#endif /* STRINGLIB_STR */
Fredrik Lundh2d23d5b2006-05-27 10:05:10 +0000100
Facundo Batista6f7e6fb2007-11-16 19:16:15 +0000101#ifdef FROM_UNICODE
102
Facundo Batista57d56692007-11-16 18:04:14 +0000103/*
104This function is a helper for the "find" family (find, rfind, index,
105rindex) of unicodeobject.c file, because they all have the same
106behaviour for the arguments.
107
108It does not touch the variables received until it knows everything
109is ok.
110
111Note that we receive a pointer to the pointer of the substring object,
112so when we create that object in this function we don't DECREF it,
113because it continues living in the caller functions (those functions,
114after finishing using the substring, must DECREF it).
115*/
116
Facundo Batista292a0692007-11-16 18:41:24 +0000117Py_LOCAL_INLINE(int)
Facundo Batista57d56692007-11-16 18:04:14 +0000118_ParseTupleFinds (PyObject *args, PyObject **substring,
119 Py_ssize_t *start, Py_ssize_t *end) {
120 PyObject *tmp_substring;
121 Py_ssize_t tmp_start = 0;
122 Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
123 PyObject *obj_start=Py_None, *obj_end=Py_None;
124
125 if (!PyArg_ParseTuple(args, "O|OO:find", &tmp_substring,
126 &obj_start, &obj_end))
127 return 0;
128
129 /* To support None in "start" and "end" arguments, meaning
130 the same as if they were not passed.
131 */
132 if (obj_start != Py_None)
133 if (!_PyEval_SliceIndex(obj_start, &tmp_start))
134 return 0;
135 if (obj_end != Py_None)
136 if (!_PyEval_SliceIndex(obj_end, &tmp_end))
137 return 0;
138
139 tmp_substring = PyUnicode_FromObject(tmp_substring);
140 if (!tmp_substring)
141 return 0;
142
143 *start = tmp_start;
144 *end = tmp_end;
145 *substring = tmp_substring;
146 return 1;
147}
148
Facundo Batista6f7e6fb2007-11-16 19:16:15 +0000149#endif /* FROM_UNICODE */
Facundo Batista57d56692007-11-16 18:04:14 +0000150
Fredrik Lundh60d8b182006-05-27 15:20:22 +0000151#endif /* STRINGLIB_FIND_H */
Fredrik Lundh58b5e842006-05-26 19:24:53 +0000152
153/*
154Local variables:
155c-basic-offset: 4
156indent-tabs-mode: nil
157End:
158*/