blob: f915296cae61350575c77d01a9c85ad34acba392 [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
Amaury Forgeot d'Arcf2e93682008-09-26 22:48:41 +000017 if (str_len < 0)
18 return -1;
19 if (sub_len == 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +000020 return offset;
21
Antoine Pitrouf2c54842010-01-13 08:07:53 +000022 pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_SEARCH);
Thomas Wouters477c8d52006-05-27 19:21:47 +000023
24 if (pos >= 0)
25 pos += offset;
26
27 return pos;
28}
29
30Py_LOCAL_INLINE(Py_ssize_t)
31stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
32 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
33 Py_ssize_t offset)
34{
Antoine Pitrouda2ecaf2010-01-02 21:40:36 +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
Antoine Pitrouf2c54842010-01-13 08:07:53 +000042 pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_RSEARCH);
Antoine Pitrouda2ecaf2010-01-02 21:40:36 +000043
44 if (pos >= 0)
45 pos += offset;
46
47 return pos;
Thomas Wouters477c8d52006-05-27 19:21:47 +000048}
49
Antoine Pitrouf2c54842010-01-13 08:07:53 +000050/* helper macro to fixup start/end slice values */
51#define ADJUST_INDICES(start, end, len) \
52 if (end > len) \
53 end = len; \
54 else if (end < 0) { \
55 end += len; \
56 if (end < 0) \
57 end = 0; \
58 } \
59 if (start < 0) { \
60 start += len; \
61 if (start < 0) \
62 start = 0; \
63 }
64
Thomas Wouters477c8d52006-05-27 19:21:47 +000065Py_LOCAL_INLINE(Py_ssize_t)
66stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
67 const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
68 Py_ssize_t start, Py_ssize_t end)
69{
Antoine Pitrouf2c54842010-01-13 08:07:53 +000070 ADJUST_INDICES(start, end, str_len);
Antoine Pitrouda2ecaf2010-01-02 21:40:36 +000071 return stringlib_find(str + start, end - start, sub, sub_len, start);
Thomas Wouters477c8d52006-05-27 19:21:47 +000072}
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{
Antoine Pitrouf2c54842010-01-13 08:07:53 +000079 ADJUST_INDICES(start, end, str_len);
Thomas Wouters477c8d52006-05-27 19:21:47 +000080 return stringlib_rfind(str + start, end - start, sub, sub_len, start);
81}
82
Christian Heimes4f3c5612008-08-28 14:55:10 +000083#ifdef STRINGLIB_WANT_CONTAINS_OBJ
Thomas Wouters477c8d52006-05-27 19:21:47 +000084
85Py_LOCAL_INLINE(int)
86stringlib_contains_obj(PyObject* str, PyObject* sub)
87{
88 return stringlib_find(
89 STRINGLIB_STR(str), STRINGLIB_LEN(str),
90 STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0
91 ) != -1;
92}
93
Antoine Pitrouf2c54842010-01-13 08:07:53 +000094#endif /* STRINGLIB_WANT_CONTAINS_OBJ */
Thomas Wouters477c8d52006-05-27 19:21:47 +000095
Antoine Pitrouf2c54842010-01-13 08:07:53 +000096#if STRINGLIB_IS_UNICODE
Christian Heimes9cd17752007-11-18 19:35:23 +000097
98/*
99This function is a helper for the "find" family (find, rfind, index,
100rindex) of unicodeobject.c file, because they all have the same
101behaviour for the arguments.
102
103It does not touch the variables received until it knows everything
104is ok.
105
106Note that we receive a pointer to the pointer of the substring object,
107so when we create that object in this function we don't DECREF it,
108because it continues living in the caller functions (those functions,
109after finishing using the substring, must DECREF it).
110*/
111
112Py_LOCAL_INLINE(int)
113_ParseTupleFinds (PyObject *args, PyObject **substring,
114 Py_ssize_t *start, Py_ssize_t *end) {
115 PyObject *tmp_substring;
116 Py_ssize_t tmp_start = 0;
117 Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
118 PyObject *obj_start=Py_None, *obj_end=Py_None;
119
120 if (!PyArg_ParseTuple(args, "O|OO:find", &tmp_substring,
121 &obj_start, &obj_end))
122 return 0;
123
124 /* To support None in "start" and "end" arguments, meaning
125 the same as if they were not passed.
126 */
127 if (obj_start != Py_None)
128 if (!_PyEval_SliceIndex(obj_start, &tmp_start))
129 return 0;
130 if (obj_end != Py_None)
131 if (!_PyEval_SliceIndex(obj_end, &tmp_end))
132 return 0;
133
134 tmp_substring = PyUnicode_FromObject(tmp_substring);
135 if (!tmp_substring)
136 return 0;
137
138 *start = tmp_start;
139 *end = tmp_end;
140 *substring = tmp_substring;
141 return 1;
142}
143
Antoine Pitrouf2c54842010-01-13 08:07:53 +0000144#endif /* STRINGLIB_IS_UNICODE */
Christian Heimes9cd17752007-11-18 19:35:23 +0000145
Thomas Wouters477c8d52006-05-27 19:21:47 +0000146#endif /* STRINGLIB_FIND_H */