| 5170 | " Str: A new string with leading and trailing characters removed."; |
| 5171 | |
| 5172 | static PyObject *Str_like_strip(PyObject *self, PyObject *const *args, Py_ssize_t positional_args_count, |
| 5173 | PyObject *args_names_tuple) { |
| 5174 | // Check arguments |
| 5175 | int is_member = self != NULL && PyObject_TypeCheck(self, &StrType); |
| 5176 | Py_ssize_t expected_min_args = !is_member; |
| 5177 | Py_ssize_t expected_max_args = !is_member + 1; |
| 5178 | if (positional_args_count < expected_min_args || positional_args_count > expected_max_args) { |
| 5179 | PyErr_SetString(PyExc_TypeError, "strip() takes at most 1 argument"); |
| 5180 | return NULL; |
| 5181 | } |
| 5182 | |
| 5183 | PyObject *text_obj = is_member ? self : args[0]; |
| 5184 | PyObject *chars_obj = positional_args_count > !is_member ? args[!is_member] : NULL; |
| 5185 | |
| 5186 | if (args_names_tuple) { |
| 5187 | Py_ssize_t args_names_count = PyTuple_GET_SIZE(args_names_tuple); |
| 5188 | for (Py_ssize_t i = 0; i < args_names_count; ++i) { |
| 5189 | PyObject *key = PyTuple_GET_ITEM(args_names_tuple, i); |
| 5190 | PyObject *value = args[positional_args_count + i]; |
| 5191 | if (PyUnicode_CompareWithASCIIString(key, "chars") == 0 && !chars_obj) { chars_obj = value; } |
| 5192 | else if (PyErr_Format(PyExc_TypeError, "Got an unexpected keyword argument '%U'", key)) |
| 5193 | return NULL; |
| 5194 | } |
| 5195 | } |
| 5196 | |
| 5197 | sz_string_view_t text; |
| 5198 | sz_string_view_t chars; |
| 5199 | |
| 5200 | // Validate and convert text |
| 5201 | if (!sz_py_export_string_like(text_obj, &text.start, &text.length)) { |
| 5202 | wrap_current_exception("The text argument must be string-like"); |
| 5203 | return NULL; |
| 5204 | } |
| 5205 | |
| 5206 | // Default to whitespace if chars is not provided |
| 5207 | char const *default_chars = " \t\n\r\f\v"; |
| 5208 | if (chars_obj) { |
| 5209 | if (!sz_py_export_string_like(chars_obj, &chars.start, &chars.length)) { |
| 5210 | wrap_current_exception("The chars argument must be string-like"); |
| 5211 | return NULL; |
| 5212 | } |
| 5213 | } |
| 5214 | else { |
| 5215 | chars.start = default_chars; |
| 5216 | chars.length = 6; |
| 5217 | } |
| 5218 | |
| 5219 | // Create byteset from chars |
| 5220 | sz_byteset_t set; |
| 5221 | sz_byteset_init(&set); |
| 5222 | for (sz_size_t i = 0; i < chars.length; ++i) sz_byteset_add(&set, chars.start[i]); |
| 5223 | sz_byteset_invert(&set); |
| 5224 | |
| 5225 | // Find first character NOT in the set (i.e., not to be stripped) |
| 5226 | sz_cptr_t new_start = sz_find_byteset(text.start, text.length, &set); |
| 5227 | if (!new_start) { |
| 5228 | // Return empty string |
| 5229 | Str *result = (Str *)StrType.tp_alloc(&StrType, 0); |
nothing calls this directly
no test coverage detected
searching dependent graphs…