]>
Commit | Line | Data |
---|---|---|
53b2ba57 DM |
1 | /* stringlib: find/index implementation */\r |
2 | \r | |
3 | #ifndef STRINGLIB_FIND_H\r | |
4 | #define STRINGLIB_FIND_H\r | |
5 | \r | |
6 | #ifndef STRINGLIB_FASTSEARCH_H\r | |
7 | #error must include "stringlib/fastsearch.h" before including this module\r | |
8 | #endif\r | |
9 | \r | |
10 | Py_LOCAL_INLINE(Py_ssize_t)\r | |
11 | stringlib_find(const STRINGLIB_CHAR* str, Py_ssize_t str_len,\r | |
12 | const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,\r | |
13 | Py_ssize_t offset)\r | |
14 | {\r | |
15 | Py_ssize_t pos;\r | |
16 | \r | |
17 | if (str_len < 0)\r | |
18 | return -1;\r | |
19 | if (sub_len == 0)\r | |
20 | return offset;\r | |
21 | \r | |
22 | pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_SEARCH);\r | |
23 | \r | |
24 | if (pos >= 0)\r | |
25 | pos += offset;\r | |
26 | \r | |
27 | return pos;\r | |
28 | }\r | |
29 | \r | |
30 | Py_LOCAL_INLINE(Py_ssize_t)\r | |
31 | stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len,\r | |
32 | const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,\r | |
33 | Py_ssize_t offset)\r | |
34 | {\r | |
35 | Py_ssize_t pos;\r | |
36 | \r | |
37 | if (str_len < 0)\r | |
38 | return -1;\r | |
39 | if (sub_len == 0)\r | |
40 | return str_len + offset;\r | |
41 | \r | |
42 | pos = fastsearch(str, str_len, sub, sub_len, -1, FAST_RSEARCH);\r | |
43 | \r | |
44 | if (pos >= 0)\r | |
45 | pos += offset;\r | |
46 | \r | |
47 | return pos;\r | |
48 | }\r | |
49 | \r | |
50 | /* helper macro to fixup start/end slice values */\r | |
51 | #define ADJUST_INDICES(start, end, len) \\r | |
52 | if (end > len) \\r | |
53 | end = len; \\r | |
54 | else if (end < 0) { \\r | |
55 | end += len; \\r | |
56 | if (end < 0) \\r | |
57 | end = 0; \\r | |
58 | } \\r | |
59 | if (start < 0) { \\r | |
60 | start += len; \\r | |
61 | if (start < 0) \\r | |
62 | start = 0; \\r | |
63 | }\r | |
64 | \r | |
65 | Py_LOCAL_INLINE(Py_ssize_t)\r | |
66 | stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,\r | |
67 | const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,\r | |
68 | Py_ssize_t start, Py_ssize_t end)\r | |
69 | {\r | |
70 | ADJUST_INDICES(start, end, str_len);\r | |
71 | return stringlib_find(str + start, end - start, sub, sub_len, start);\r | |
72 | }\r | |
73 | \r | |
74 | Py_LOCAL_INLINE(Py_ssize_t)\r | |
75 | stringlib_rfind_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,\r | |
76 | const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,\r | |
77 | Py_ssize_t start, Py_ssize_t end)\r | |
78 | {\r | |
79 | ADJUST_INDICES(start, end, str_len);\r | |
80 | return stringlib_rfind(str + start, end - start, sub, sub_len, start);\r | |
81 | }\r | |
82 | \r | |
83 | #ifdef STRINGLIB_WANT_CONTAINS_OBJ\r | |
84 | \r | |
85 | Py_LOCAL_INLINE(int)\r | |
86 | stringlib_contains_obj(PyObject* str, PyObject* sub)\r | |
87 | {\r | |
88 | return stringlib_find(\r | |
89 | STRINGLIB_STR(str), STRINGLIB_LEN(str),\r | |
90 | STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0\r | |
91 | ) != -1;\r | |
92 | }\r | |
93 | \r | |
94 | #endif /* STRINGLIB_WANT_CONTAINS_OBJ */\r | |
95 | \r | |
96 | /*\r | |
97 | This function is a helper for the "find" family (find, rfind, index,\r | |
98 | rindex) and for count, startswith and endswith, because they all have\r | |
99 | the same behaviour for the arguments.\r | |
100 | \r | |
101 | It does not touch the variables received until it knows everything \r | |
102 | is ok.\r | |
103 | */\r | |
104 | \r | |
105 | #define FORMAT_BUFFER_SIZE 50\r | |
106 | \r | |
107 | Py_LOCAL_INLINE(int)\r | |
108 | stringlib_parse_args_finds(const char * function_name, PyObject *args,\r | |
109 | PyObject **subobj,\r | |
110 | Py_ssize_t *start, Py_ssize_t *end)\r | |
111 | {\r | |
112 | PyObject *tmp_subobj;\r | |
113 | Py_ssize_t tmp_start = 0;\r | |
114 | Py_ssize_t tmp_end = PY_SSIZE_T_MAX;\r | |
115 | PyObject *obj_start=Py_None, *obj_end=Py_None;\r | |
116 | char format[FORMAT_BUFFER_SIZE] = "O|OO:";\r | |
117 | size_t len = strlen(format);\r | |
118 | \r | |
119 | strncpy(format + len, function_name, FORMAT_BUFFER_SIZE - len - 1);\r | |
120 | format[FORMAT_BUFFER_SIZE - 1] = '\0';\r | |
121 | \r | |
122 | if (!PyArg_ParseTuple(args, format, &tmp_subobj, &obj_start, &obj_end))\r | |
123 | return 0;\r | |
124 | \r | |
125 | /* To support None in "start" and "end" arguments, meaning\r | |
126 | the same as if they were not passed.\r | |
127 | */\r | |
128 | if (obj_start != Py_None)\r | |
129 | if (!_PyEval_SliceIndex(obj_start, &tmp_start))\r | |
130 | return 0;\r | |
131 | if (obj_end != Py_None)\r | |
132 | if (!_PyEval_SliceIndex(obj_end, &tmp_end))\r | |
133 | return 0;\r | |
134 | \r | |
135 | *start = tmp_start;\r | |
136 | *end = tmp_end;\r | |
137 | *subobj = tmp_subobj;\r | |
138 | return 1;\r | |
139 | }\r | |
140 | \r | |
141 | #undef FORMAT_BUFFER_SIZE\r | |
142 | \r | |
143 | #if STRINGLIB_IS_UNICODE\r | |
144 | \r | |
145 | /*\r | |
146 | Wraps stringlib_parse_args_finds() and additionally ensures that the\r | |
147 | first argument is a unicode object.\r | |
148 | \r | |
149 | Note that we receive a pointer to the pointer of the substring object,\r | |
150 | so when we create that object in this function we don't DECREF it,\r | |
151 | because it continues living in the caller functions (those functions, \r | |
152 | after finishing using the substring, must DECREF it).\r | |
153 | */\r | |
154 | \r | |
155 | Py_LOCAL_INLINE(int)\r | |
156 | stringlib_parse_args_finds_unicode(const char * function_name, PyObject *args,\r | |
157 | PyUnicodeObject **substring,\r | |
158 | Py_ssize_t *start, Py_ssize_t *end)\r | |
159 | {\r | |
160 | PyObject *tmp_substring;\r | |
161 | \r | |
162 | if(stringlib_parse_args_finds(function_name, args, &tmp_substring,\r | |
163 | start, end)) {\r | |
164 | tmp_substring = PyUnicode_FromObject(tmp_substring);\r | |
165 | if (!tmp_substring)\r | |
166 | return 0;\r | |
167 | *substring = (PyUnicodeObject *)tmp_substring;\r | |
168 | return 1;\r | |
169 | }\r | |
170 | return 0;\r | |
171 | }\r | |
172 | \r | |
173 | #endif /* STRINGLIB_IS_UNICODE */\r | |
174 | \r | |
175 | #endif /* STRINGLIB_FIND_H */\r |