about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/common.c22
-rw-r--r--tests/unittests/test_common.c32
-rw-r--r--tests/unittests/unittests.c2
3 files changed, 48 insertions, 8 deletions
diff --git a/src/common.c b/src/common.c
index d3f09a56..9544ab73 100644
--- a/src/common.c
+++ b/src/common.c
@@ -509,13 +509,18 @@ prof_occurrences(const char *const needle, const char *const haystack, int offse
         return *result;
     }
 
-    if (g_str_has_prefix(&haystack[offset], needle)) {
+    gchar *haystack_curr = g_utf8_offset_to_pointer(haystack, offset);
+    if (g_str_has_prefix(haystack_curr, needle)) {
         if (whole_word) {
-            char *prev = g_utf8_prev_char(&haystack[offset]);
-            char *next = g_utf8_next_char(&haystack[offset] + strlen(needle) - 1);
-            gunichar prevu = g_utf8_get_char(prev);
-            gunichar nextu = g_utf8_get_char(next);
-            if (!g_unichar_isalnum(prevu) && !g_unichar_isalnum(nextu)) {
+            gchar *needle_last_ch = g_utf8_offset_to_pointer(needle, g_utf8_strlen(needle, -1)- 1);
+            int needle_last_ch_len = mblen(needle_last_ch, MB_CUR_MAX);
+
+            gchar *haystack_before_ch = g_utf8_prev_char(haystack_curr);
+            gchar *haystack_after_ch = g_utf8_next_char(haystack_curr + strlen(needle) - needle_last_ch_len);
+
+            gunichar before = g_utf8_get_char(haystack_before_ch);
+            gunichar 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));
             }
         } else {
@@ -523,8 +528,9 @@ prof_occurrences(const char *const needle, const char *const haystack, int offse
         }
     }
 
-    if (haystack[offset+1] != '\0') {
-        *result = prof_occurrences(needle, haystack, offset+1, whole_word, result);
+    offset++;
+    if (g_strcmp0(g_utf8_offset_to_pointer(haystack, offset), "\0") != 0) {
+        *result = prof_occurrences(needle, haystack, offset, whole_word, result);
     }
 
     return *result;
diff --git a/tests/unittests/test_common.c b/tests/unittests/test_common.c
index d03f2123..75eed6e2 100644
--- a/tests/unittests/test_common.c
+++ b/tests/unittests/test_common.c
@@ -444,6 +444,13 @@ void prof_whole_occurrences_tests(void **state)
     assert_true(_lists_equal(prof_occurrences("boothj5", "boothj5, hi",  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
     g_slist_free(expected); expected = NULL;
 
+    expected = g_slist_append(expected, GINT_TO_POINTER(0));
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而",      0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而 hi",   0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而: hi",  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而, hi",  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    g_slist_free(expected); expected = NULL;
+
     expected = g_slist_append(expected, GINT_TO_POINTER(6));
     assert_true(_lists_equal(prof_occurrences("boothj5", "hello boothj5",        0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
     assert_true(_lists_equal(prof_occurrences("boothj5", "hello boothj5 there",  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
@@ -451,6 +458,12 @@ void prof_whole_occurrences_tests(void **state)
     g_slist_free(expected); expected = NULL;
 
     expected = g_slist_append(expected, GINT_TO_POINTER(6));
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hello 我能吞下玻璃而",        0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hello 我能吞下玻璃而 there",  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "heyy @我能吞下玻璃而, there", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    g_slist_free(expected); expected = NULL;
+
+    expected = g_slist_append(expected, GINT_TO_POINTER(6));
     expected = g_slist_append(expected, GINT_TO_POINTER(26));
     assert_true(_lists_equal(prof_occurrences("boothj5", "hello boothj5 some more a boothj5 stuff",  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
     assert_true(_lists_equal(prof_occurrences("boothj5", "hello boothj5 there ands #boothj5",        0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
@@ -458,6 +471,13 @@ void prof_whole_occurrences_tests(void **state)
     g_slist_free(expected); expected = NULL;
 
     expected = g_slist_append(expected, GINT_TO_POINTER(6));
+    expected = g_slist_append(expected, GINT_TO_POINTER(26));
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hello 我能吞下玻璃而 some more a 我能吞下玻璃而 stuff",  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hello 我能吞下玻璃而 there ands #我能吞下玻璃而",        0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "heyy @我能吞下玻璃而, there hows 我能吞下玻璃而?",       0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    g_slist_free(expected); expected = NULL;
+
+    expected = g_slist_append(expected, GINT_TO_POINTER(6));
     assert_true(_lists_equal(prof_occurrences("p", "ppppp p",   0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
     g_slist_free(expected); expected = NULL;
 
@@ -488,4 +508,16 @@ void prof_whole_occurrences_tests(void **state)
     assert_true(_lists_equal(prof_occurrences("k",       "kk",                  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
     assert_true(_lists_equal(prof_occurrences("k",       "kkkkkkk",                  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
     g_slist_free(expected); expected = NULL;
+
+    expected = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而hello",        0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey我能吞下玻璃而",          0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey我能吞下玻璃而hithere",   0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey 我能吞下玻璃而hithere",  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey @我能吞下玻璃而hithere", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey我能吞下玻璃而 hithere",  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey我能吞下玻璃而, hithere", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而我能吞下玻璃而",      0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而fill我能吞下玻璃而",  0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL;
+    g_slist_free(expected); expected = NULL;
 }
diff --git a/tests/unittests/unittests.c b/tests/unittests/unittests.c
index e0a5dd34..71bdf1b1 100644
--- a/tests/unittests/unittests.c
+++ b/tests/unittests/unittests.c
@@ -6,6 +6,7 @@
 #include <setjmp.h>
 #include <cmocka.h>
 #include <sys/stat.h>
+#include <locale.h>
 
 #include "config.h"
 #include "xmpp/chat_session.h"
@@ -37,6 +38,7 @@
 #include "test_plugins_disco.h"
 
 int main(int argc, char* argv[]) {
+    setlocale(LC_ALL, "");
     const UnitTest all_tests[] = {
 
         unit_test(replace_one_substr),