mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-07-19 09:36:21 +00:00
refactor: optimize prof_occurrences()
Optimize prof_occurrences by using pointer arithmetic and g_utf8_next_char instead of calls to g_utf8_offset_to_pointer. Improve list construction efficiency in prof_occurrences by using g_slist_prepend and g_slist_reverse instead of appends. Also fix a slight oversight that could lead to trouble: When empty search strings (e.g. empty nicks) are passed it caused matches at every position. Update the test case to test for empty nicks.
This commit is contained in:
32
src/common.c
32
src/common.c
@@ -578,36 +578,48 @@ is_notify_enabled(void)
|
||||
GSList*
|
||||
prof_occurrences(const char* const needle, const char* const haystack, int offset, gboolean whole_word, GSList** result)
|
||||
{
|
||||
if (needle == NULL || haystack == NULL) {
|
||||
if (needle == NULL || haystack == NULL || *needle == '\0') {
|
||||
return *result;
|
||||
}
|
||||
|
||||
do {
|
||||
gchar* haystack_curr = g_utf8_offset_to_pointer(haystack, offset);
|
||||
if (g_str_has_prefix(haystack_curr, needle)) {
|
||||
size_t needle_len = strlen(needle);
|
||||
gchar* p = g_utf8_offset_to_pointer(haystack, offset);
|
||||
GSList* matches = NULL;
|
||||
|
||||
while (p) {
|
||||
if (g_str_has_prefix(p, needle)) {
|
||||
if (whole_word) {
|
||||
gunichar before = 0;
|
||||
gchar* haystack_before_ch = g_utf8_find_prev_char(haystack, haystack_curr);
|
||||
gchar* haystack_before_ch = g_utf8_find_prev_char(haystack, p);
|
||||
if (haystack_before_ch) {
|
||||
before = g_utf8_get_char(haystack_before_ch);
|
||||
}
|
||||
|
||||
gunichar after = 0;
|
||||
gchar* haystack_after_ch = haystack_curr + strlen(needle);
|
||||
if (haystack_after_ch[0] != '\0') {
|
||||
gchar* haystack_after_ch = p + needle_len;
|
||||
if (*haystack_after_ch != '\0') {
|
||||
after = g_utf8_get_char(haystack_after_ch);
|
||||
}
|
||||
|
||||
if (!g_unichar_isalnum(before) && !g_unichar_isalnum(after)) {
|
||||
*result = g_slist_append(*result, GINT_TO_POINTER(offset));
|
||||
matches = g_slist_prepend(matches, GINT_TO_POINTER(offset));
|
||||
}
|
||||
} else {
|
||||
*result = g_slist_append(*result, GINT_TO_POINTER(offset));
|
||||
matches = g_slist_prepend(matches, GINT_TO_POINTER(offset));
|
||||
}
|
||||
}
|
||||
|
||||
if (*p == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
p = g_utf8_next_char(p);
|
||||
offset++;
|
||||
} while (g_strcmp0(g_utf8_offset_to_pointer(haystack, offset), "\0") != 0);
|
||||
}
|
||||
|
||||
if (matches) {
|
||||
*result = g_slist_concat(*result, g_slist_reverse(matches));
|
||||
}
|
||||
|
||||
return *result;
|
||||
}
|
||||
|
||||
@@ -923,6 +923,11 @@ get_mentions_tests(void** state)
|
||||
assert_true(_lists_equal(actual, expected)); // expected is NULL
|
||||
g_slist_free(actual); actual = NULL;
|
||||
|
||||
// Empty nick
|
||||
actual = get_mentions(FALSE, TRUE, "hello", "");
|
||||
assert_true(_lists_equal(actual, expected)); // expected is NULL
|
||||
g_slist_free(actual); actual = NULL;
|
||||
|
||||
// UTF-8 characters
|
||||
expected = g_slist_append(expected, GINT_TO_POINTER(0));
|
||||
actual = get_mentions(TRUE, TRUE, "我能 hello", "我能");
|
||||
|
||||
Reference in New Issue
Block a user