|
1 /* 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 |
|
10 Py_LOCAL_INLINE(Py_ssize_t) |
|
11 stringlib_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 |
|
17 if (str_len < 0) |
|
18 return -1; |
|
19 if (sub_len == 0) |
|
20 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; |
|
28 } |
|
29 |
|
30 Py_LOCAL_INLINE(Py_ssize_t) |
|
31 stringlib_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 { |
|
35 /* XXX - create reversefastsearch helper! */ |
|
36 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; |
|
42 for (j = str_len - sub_len; j >= 0; --j) |
|
43 if (STRINGLIB_CMP(str+j, sub, sub_len) == 0) { |
|
44 pos = j + offset; |
|
45 break; |
|
46 } |
|
47 return pos; |
|
48 } |
|
49 } |
|
50 |
|
51 Py_LOCAL_INLINE(Py_ssize_t) |
|
52 stringlib_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) |
|
55 { |
|
56 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 |
|
67 return stringlib_find( |
|
68 str + start, end - start, |
|
69 sub, sub_len, start |
|
70 ); |
|
71 } |
|
72 |
|
73 Py_LOCAL_INLINE(Py_ssize_t) |
|
74 stringlib_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 |
|
92 #if defined(STRINGLIB_STR) && !defined(FROM_BYTEARRAY) |
|
93 |
|
94 Py_LOCAL_INLINE(int) |
|
95 stringlib_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 |
|
103 #endif /* STRINGLIB_STR */ |
|
104 |
|
105 #ifdef FROM_UNICODE |
|
106 |
|
107 /* |
|
108 This function is a helper for the "find" family (find, rfind, index, |
|
109 rindex) of unicodeobject.c file, because they all have the same |
|
110 behaviour for the arguments. |
|
111 |
|
112 It does not touch the variables received until it knows everything |
|
113 is ok. |
|
114 |
|
115 Note that we receive a pointer to the pointer of the substring object, |
|
116 so when we create that object in this function we don't DECREF it, |
|
117 because it continues living in the caller functions (those functions, |
|
118 after finishing using the substring, must DECREF it). |
|
119 */ |
|
120 |
|
121 Py_LOCAL_INLINE(int) |
|
122 _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 |
|
153 #endif /* FROM_UNICODE */ |
|
154 |
|
155 #endif /* STRINGLIB_FIND_H */ |
|
156 |
|
157 /* |
|
158 Local variables: |
|
159 c-basic-offset: 4 |
|
160 indent-tabs-mode: nil |
|
161 End: |
|
162 */ |