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 (sub_len == 0) {
|
---|
18 | if (str_len < 0)
|
---|
19 | return -1;
|
---|
20 | return offset;
|
---|
21 | }
|
---|
22 |
|
---|
23 | pos = fastsearch(str, str_len, sub, sub_len, FAST_SEARCH);
|
---|
24 |
|
---|
25 | if (pos >= 0)
|
---|
26 | pos += offset;
|
---|
27 |
|
---|
28 | return pos;
|
---|
29 | }
|
---|
30 |
|
---|
31 | Py_LOCAL_INLINE(Py_ssize_t)
|
---|
32 | stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
|
---|
33 | const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
|
---|
34 | Py_ssize_t offset)
|
---|
35 | {
|
---|
36 | /* XXX - create reversefastsearch helper! */
|
---|
37 | 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;
|
---|
43 | for (j = str_len - sub_len; j >= 0; --j)
|
---|
44 | if (STRINGLIB_CMP(str+j, sub, sub_len) == 0) {
|
---|
45 | pos = j + offset;
|
---|
46 | break;
|
---|
47 | }
|
---|
48 | return pos;
|
---|
49 | }
|
---|
50 | }
|
---|
51 |
|
---|
52 | Py_LOCAL_INLINE(Py_ssize_t)
|
---|
53 | stringlib_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)
|
---|
56 | {
|
---|
57 | 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 |
|
---|
68 | return stringlib_find(
|
---|
69 | str + start, end - start,
|
---|
70 | sub, sub_len, start
|
---|
71 | );
|
---|
72 | }
|
---|
73 |
|
---|
74 | Py_LOCAL_INLINE(Py_ssize_t)
|
---|
75 | stringlib_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 |
|
---|
93 | #ifdef STRINGLIB_STR
|
---|
94 |
|
---|
95 | Py_LOCAL_INLINE(int)
|
---|
96 | stringlib_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 |
|
---|
104 | #endif /* STRINGLIB_STR */
|
---|
105 |
|
---|
106 | #endif /* STRINGLIB_FIND_H */
|
---|
107 |
|
---|
108 | /*
|
---|
109 | Local variables:
|
---|
110 | c-basic-offset: 4
|
---|
111 | indent-tabs-mode: nil
|
---|
112 | End:
|
---|
113 | */
|
---|