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 | */
|
---|