| 4758 | " [Str('Straße'), Str('STRASSE')]"; |
| 4759 | |
| 4760 | static PyObject *Str_like_utf8_case_insensitive_find_iter(PyObject *self, PyObject *const *args, |
| 4761 | Py_ssize_t positional_args_count, PyObject *kwnames) { |
| 4762 | // Check if called as member or module function |
| 4763 | int is_member = self != NULL && PyObject_TypeCheck(self, &StrType); |
| 4764 | int min_args = is_member ? 1 : 2; |
| 4765 | int max_args = is_member ? 2 : 3; |
| 4766 | |
| 4767 | if (positional_args_count < min_args || positional_args_count > max_args) { |
| 4768 | PyErr_Format(PyExc_TypeError, |
| 4769 | "utf8_case_insensitive_find_iter() requires %d to %d positional arguments, got %zd", min_args, |
| 4770 | max_args, positional_args_count); |
| 4771 | return NULL; |
| 4772 | } |
| 4773 | |
| 4774 | PyObject *haystack_obj = is_member ? self : args[0]; |
| 4775 | PyObject *needle_obj = is_member ? args[0] : args[1]; |
| 4776 | int include_overlapping = 0; |
| 4777 | |
| 4778 | // Parse keyword arguments |
| 4779 | if (kwnames) { |
| 4780 | Py_ssize_t n_kwnames = PyTuple_GET_SIZE(kwnames); |
| 4781 | for (Py_ssize_t i = 0; i < n_kwnames; ++i) { |
| 4782 | PyObject *key = PyTuple_GET_ITEM(kwnames, i); |
| 4783 | PyObject *value = args[positional_args_count + i]; |
| 4784 | if (PyUnicode_CompareWithASCIIString(key, "include_overlapping") == 0) { |
| 4785 | include_overlapping = PyObject_IsTrue(value); |
| 4786 | } |
| 4787 | else { |
| 4788 | PyErr_Format(PyExc_TypeError, "utf8_case_insensitive_find_iter() got unexpected keyword argument '%U'", |
| 4789 | key); |
| 4790 | return NULL; |
| 4791 | } |
| 4792 | } |
| 4793 | } |
| 4794 | |
| 4795 | // Check positional include_overlapping argument |
| 4796 | if (positional_args_count > max_args - 1) include_overlapping = PyObject_IsTrue(args[is_member ? 1 : 2]); |
| 4797 | |
| 4798 | // Extract haystack and needle views |
| 4799 | sz_string_view_t haystack_view, needle_view; |
| 4800 | if (!sz_py_export_string_like(haystack_obj, &haystack_view.start, &haystack_view.length) || |
| 4801 | !sz_py_export_string_like(needle_obj, &needle_view.start, &needle_view.length)) { |
| 4802 | return NULL; // Exception already set by helper |
| 4803 | } |
| 4804 | |
| 4805 | // Handle edge case: empty needle yields nothing |
| 4806 | if (needle_view.length == 0) { |
| 4807 | // Return an empty iterator by setting current = end |
| 4808 | Utf8CaseInsensitiveFindIterator *iter = |
| 4809 | PyObject_New(Utf8CaseInsensitiveFindIterator, &Utf8CaseInsensitiveFindIteratorType); |
| 4810 | if (!iter) return PyErr_NoMemory(); |
| 4811 | |
| 4812 | iter->haystack_obj = haystack_obj; |
| 4813 | Py_INCREF(haystack_obj); |
| 4814 | iter->needle_obj = needle_obj; |
| 4815 | Py_INCREF(needle_obj); |
| 4816 | iter->current = haystack_view.start + haystack_view.length; // Start at end = empty iterator |
| 4817 | iter->haystack_end = haystack_view.start + haystack_view.length; |
nothing calls this directly
no test coverage detected
searching dependent graphs…