Branch data 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 : 3383187 : 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 : : assert(str_len >= 0);
15 [ + + ]: 3383187 : if (sub_len == 0)
16 : 8493 : return offset;
17 : :
18 : 3374694 : pos = FASTSEARCH(str, str_len, sub, sub_len, -1, FAST_SEARCH);
19 : :
20 [ + + ]: 3374694 : if (pos >= 0)
21 : 782917 : pos += offset;
22 : :
23 : 3374694 : 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 : : 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 : 559970 : 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 : 559970 : 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 : 15171655 : 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 : 15171655 : Py_ssize_t tmp_start = 0;
92 : 15171655 : Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
93 : 15171655 : PyObject *obj_start=Py_None, *obj_end=Py_None;
94 : 15171655 : char format[FORMAT_BUFFER_SIZE] = "O|OO:";
95 : 15171655 : size_t len = strlen(format);
96 : :
97 : 15171655 : strncpy(format + len, function_name, FORMAT_BUFFER_SIZE - len - 1);
98 : 15171655 : format[FORMAT_BUFFER_SIZE - 1] = '\0';
99 : :
100 [ + + ]: 15171655 : 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 [ + + ]: 15171609 : if (obj_start != Py_None)
107 [ - + ]: 4534460 : if (!_PyEval_SliceIndex(obj_start, &tmp_start))
108 : 0 : return 0;
109 [ + + ]: 15171609 : if (obj_end != Py_None)
110 [ - + ]: 356784 : if (!_PyEval_SliceIndex(obj_end, &tmp_end))
111 : 0 : return 0;
112 : :
113 : 15171609 : *start = tmp_start;
114 : 15171609 : *end = tmp_end;
115 : 15171609 : *subobj = tmp_subobj;
116 : 15171609 : return 1;
117 : : }
118 : :
119 : : #undef FORMAT_BUFFER_SIZE
|