Line data Source code
1 : /* stringlib: find/index implementation */
2 :
3 : #ifndef STRINGLIB_FASTSEARCH_H
4 : #error must include "stringlib/fastsearch.h" before including this module
5 : #endif
6 :
7 : Py_LOCAL_INLINE(Py_ssize_t)
8 3425174 : STRINGLIB(find)(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
9 : const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
10 : Py_ssize_t offset)
11 : {
12 : Py_ssize_t pos;
13 :
14 3425174 : assert(str_len >= 0);
15 3425174 : if (sub_len == 0)
16 8617 : return offset;
17 :
18 3416559 : pos = FASTSEARCH(str, str_len, sub, sub_len, -1, FAST_SEARCH);
19 :
20 3416559 : if (pos >= 0)
21 800945 : pos += offset;
22 :
23 3416559 : return pos;
24 : }
25 :
26 : Py_LOCAL_INLINE(Py_ssize_t)
27 394162 : STRINGLIB(rfind)(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
28 : const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
29 : Py_ssize_t offset)
30 : {
31 : Py_ssize_t pos;
32 :
33 394162 : assert(str_len >= 0);
34 394162 : if (sub_len == 0)
35 1476 : return str_len + offset;
36 :
37 392686 : pos = FASTSEARCH(str, str_len, sub, sub_len, -1, FAST_RSEARCH);
38 :
39 392686 : if (pos >= 0)
40 11375 : pos += offset;
41 :
42 392686 : return pos;
43 : }
44 :
45 : Py_LOCAL_INLINE(Py_ssize_t)
46 559983 : STRINGLIB(find_slice)(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
47 : const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
48 : Py_ssize_t start, Py_ssize_t end)
49 : {
50 559983 : return STRINGLIB(find)(str + start, end - start, sub, sub_len, start);
51 : }
52 :
53 : Py_LOCAL_INLINE(Py_ssize_t)
54 394155 : STRINGLIB(rfind_slice)(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
55 : const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
56 : Py_ssize_t start, Py_ssize_t end)
57 : {
58 394155 : return STRINGLIB(rfind)(str + start, end - start, sub, sub_len, start);
59 : }
60 :
61 : #ifdef STRINGLIB_WANT_CONTAINS_OBJ
62 :
63 : Py_LOCAL_INLINE(int)
64 : STRINGLIB(contains_obj)(PyObject* str, PyObject* sub)
65 : {
66 : return STRINGLIB(find)(
67 : STRINGLIB_STR(str), STRINGLIB_LEN(str),
68 : STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0
69 : ) != -1;
70 : }
71 :
72 : #endif /* STRINGLIB_WANT_CONTAINS_OBJ */
73 :
74 : /*
75 : This function is a helper for the "find" family (find, rfind, index,
76 : rindex) and for count, startswith and endswith, because they all have
77 : the same behaviour for the arguments.
78 :
79 : It does not touch the variables received until it knows everything
80 : is ok.
81 : */
82 :
83 : #define FORMAT_BUFFER_SIZE 50
84 :
85 : Py_LOCAL_INLINE(int)
86 15190370 : STRINGLIB(parse_args_finds)(const char * function_name, PyObject *args,
87 : PyObject **subobj,
88 : Py_ssize_t *start, Py_ssize_t *end)
89 : {
90 : PyObject *tmp_subobj;
91 15190370 : Py_ssize_t tmp_start = 0;
92 15190370 : Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
93 15190370 : PyObject *obj_start=Py_None, *obj_end=Py_None;
94 15190370 : char format[FORMAT_BUFFER_SIZE] = "O|OO:";
95 15190370 : size_t len = strlen(format);
96 :
97 15190370 : strncpy(format + len, function_name, FORMAT_BUFFER_SIZE - len - 1);
98 15190370 : format[FORMAT_BUFFER_SIZE - 1] = '\0';
99 :
100 15190370 : if (!PyArg_ParseTuple(args, format, &tmp_subobj, &obj_start, &obj_end))
101 46 : return 0;
102 :
103 : /* To support None in "start" and "end" arguments, meaning
104 : the same as if they were not passed.
105 : */
106 15190350 : if (obj_start != Py_None)
107 4472631 : if (!_PyEval_SliceIndex(obj_start, &tmp_start))
108 0 : return 0;
109 15190350 : if (obj_end != Py_None)
110 356816 : if (!_PyEval_SliceIndex(obj_end, &tmp_end))
111 0 : return 0;
112 :
113 15190350 : *start = tmp_start;
114 15190350 : *end = tmp_end;
115 15190350 : *subobj = tmp_subobj;
116 15190350 : return 1;
117 : }
118 :
119 : #undef FORMAT_BUFFER_SIZE
|