MCPcopy Create free account
hub / github.com/ashvardanian/StringZilla / Str_like_utf8_case_insensitive_find_iter

Function Str_like_utf8_case_insensitive_find_iter

python/stringzilla.c:4760–4841  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4758 " [Str('Straße'), Str('STRASSE')]";
4759
4760static 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;

Callers

nothing calls this directly

Calls 2

sz_py_export_string_likeFunction · 0.85
memsetFunction · 0.50

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…