about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/common.c72
-rw-r--r--src/common.h3
-rw-r--r--src/event/server_events.c14
-rw-r--r--tests/unittests/test_common.c171
-rw-r--r--tests/unittests/test_common.h1
-rw-r--r--tests/unittests/unittests.c10
6 files changed, 179 insertions, 92 deletions
diff --git a/src/common.c b/src/common.c
index ad66015f..c6ead0ba 100644
--- a/src/common.c
+++ b/src/common.c
@@ -199,18 +199,6 @@ str_replace(const char *string, const char *substr,
     return newstr;
 }
 
-gboolean
-str_contains_str(const char *const searchstr, const char *const substr)
-{
-    if (!searchstr) {
-        return FALSE;
-    }
-    if (!substr) {
-        return FALSE;
-    }
-    return g_strrstr(searchstr, substr) != NULL;
-}
-
 int
 str_contains(const char str[], int size, char ch)
 {
@@ -669,3 +657,63 @@ is_notify_enabled(void)
 
     return notify_enabled;
 }
+
+gboolean
+prof_strstr(const char *const needle, const char *const haystack, gboolean case_sensitive, gboolean whole_word)
+{
+    if (needle == NULL || haystack == NULL) {
+        return FALSE;
+    }
+
+    char *needle_str = case_sensitive ? strdup(needle) : g_utf8_strdown(needle, -1);
+    char *haystack_str = case_sensitive ? strdup(haystack) : g_utf8_strdown(haystack, -1);
+
+    if (whole_word) {
+        if (g_strcmp0(needle_str, haystack_str) == 0) {
+            free(needle_str);
+            free(haystack_str);
+            return TRUE;
+        }
+
+        char *pos = g_strrstr(haystack_str, needle_str);
+        if (pos == NULL) {
+            free(needle_str);
+            free(haystack_str);
+            return FALSE;
+        }
+
+        gboolean at_start = g_str_has_prefix(haystack_str, needle_str);
+        gboolean at_end = g_str_has_suffix(haystack_str, needle_str);
+
+        if (at_start) {
+            char *next = g_utf8_next_char(pos + strlen(needle_str) - 1);
+            gunichar nextu = g_utf8_get_char(next);
+            gboolean result = g_unichar_isalnum(nextu) ? FALSE : TRUE;
+            free(needle_str);
+            free(haystack_str);
+            return result;
+        } else if (at_end) {
+            char *prev = g_utf8_prev_char(pos);
+            gunichar prevu = g_utf8_get_char(prev);
+            gboolean result = g_unichar_isalnum(prevu) ? FALSE : TRUE;
+            free(needle_str);
+            free(haystack_str);
+            return result;
+        } else {
+            char *prev = g_utf8_prev_char(pos);
+            char *next = g_utf8_next_char(pos + strlen(needle_str) - 1);
+            gunichar prevu = g_utf8_get_char(prev);
+            gunichar nextu = g_utf8_get_char(next);
+            gboolean result = g_unichar_isalnum(prevu) || g_unichar_isalnum(nextu) ? FALSE : TRUE;
+            free(needle_str);
+            free(haystack_str);
+            return result;
+        }
+    } else {
+        gboolean result = g_strrstr(haystack_str, needle_str) != NULL ? TRUE : FALSE;
+        free(needle_str);
+        free(haystack_str);
+        return result;
+    }
+}
+
diff --git a/src/common.h b/src/common.h
index 21e9c4e2..284a096e 100644
--- a/src/common.h
+++ b/src/common.h
@@ -103,7 +103,6 @@ gboolean p_hash_table_contains(GHashTable *hash_table, gconstpointer key);
 gboolean create_dir(char *name);
 gboolean mkdir_recursive(const char *dir);
 char* str_replace(const char *string, const char *substr, const char *replacement);
-gboolean str_contains_str(const char *const searchstr, const char *const substr);
 int str_contains(const char str[], int size, char ch);
 gboolean strtoi_range(char *str, int *saveptr, int min, int max, char **err_msg);
 int utf8_display_len(const char *const str);
@@ -129,4 +128,6 @@ char* get_file_or_linked(char *loc, char *basedir);
 char* strip_arg_quotes(const char *const input);
 gboolean is_notify_enabled(void);
 
+gboolean prof_strstr(const char *const needle, const char *const haystack, gboolean case_sensitive, gboolean whole_word);
+
 #endif
diff --git a/src/event/server_events.c b/src/event/server_events.c
index 48e79d3b..2712ba56 100644
--- a/src/event/server_events.c
+++ b/src/event/server_events.c
@@ -251,15 +251,11 @@ sv_ev_room_message(const char *const room_jid, const char *const nick, const cha
     char *new_message = plugins_pre_room_message_display(room_jid, nick, message);
     char *mynick = muc_nick(mucwin->roomjid);
 
-    gboolean mention = FALSE;
-    char *message_lower = g_utf8_strdown(new_message, -1);
-    char *mynick_lower = g_utf8_strdown(mynick, -1);
-    if (g_strrstr(message_lower, mynick_lower)) {
-        mention = TRUE;
-    }
-    g_free(message_lower);
-    g_free(mynick_lower);
-
+//    gboolean case_sensitive = prefs_get_boolean(PREF_MENTION_CASE_SENSITIVE);
+//    gboolean whole_word = prefs_get_boolean(PREF_MENTION_WHOLE_WORD);
+    gboolean case_sensitive = FALSE;
+    gboolean whole_word = FALSE;
+    gboolean mention = prof_strstr(mynick, new_message, case_sensitive, whole_word);
     GList *triggers = prefs_message_get_triggers(new_message);
 
     mucwin_message(mucwin, nick, new_message, mention, triggers);
diff --git a/tests/unittests/test_common.c b/tests/unittests/test_common.c
index 0e26b704..e80edb1c 100644
--- a/tests/unittests/test_common.c
+++ b/tests/unittests/test_common.c
@@ -631,66 +631,113 @@ void strip_quotes_strips_both(void **state)
     free(result);
 }
 
-void str_not_contains_str(void **state)
-{
-    char *main = "somestring";
-    char *occur = "not";
-
-    assert_false(str_contains_str(main, occur));
-}
-
-void str_contains_str_at_start(void **state)
-{
-    char *main = "somestring";
-    char *occur = "some";
-
-    assert_true(str_contains_str(main, occur));
-}
-
-void str_contains_str_at_end(void **state)
-{
-    char *main = "somestring";
-    char *occur = "string";
-
-    assert_true(str_contains_str(main, occur));
-}
-
-void str_contains_str_in_middle(void **state)
-{
-    char *main = "somestring";
-    char *occur = "str";
-
-    assert_true(str_contains_str(main, occur));
-}
-
-void str_contains_str_whole(void **state)
-{
-    char *main = "somestring";
-    char *occur = "somestring";
-
-    assert_true(str_contains_str(main, occur));
-}
-
-void str_empty_not_contains_str(void **state)
-{
-    char *main = NULL;
-    char *occur = "str";
-
-    assert_false(str_contains_str(main, occur));
-}
-
-void str_not_contains_str_empty(void **state)
-{
-    char *main = "somestring";
-    char *occur = NULL;
-
-    assert_false(str_contains_str(main, occur));
-}
-
-void str_empty_not_contains_str_empty(void **state)
-{
-    char *main = NULL;
-    char *occur = NULL;
-
-    assert_false(str_contains_str(main, occur));
+void prof_strstr_contains(void **state)
+{
+    assert_true(prof_strstr(NULL,      "some string",           FALSE, FALSE) == FALSE);
+    assert_true(prof_strstr("boothj5", NULL,                    FALSE, FALSE) == FALSE);
+    assert_true(prof_strstr(NULL,      NULL,                    FALSE, FALSE) == FALSE);
+
+    assert_true(prof_strstr("boothj5", "boothj5",               FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("boothj5", "boothj5 hello",         FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("boothj5", "hello boothj5",         FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("boothj5", "hello boothj5 there",   FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("boothj5", "helloboothj5test",      FALSE, FALSE) == TRUE);
+
+    assert_true(prof_strstr("boothj5", "BoothJ5",               FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("boothj5", "BoothJ5 hello",         FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("boothj5", "hello BoothJ5",         FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("boothj5", "hello BoothJ5 there",   FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("boothj5", "helloBoothJ5test",      FALSE, FALSE) == TRUE);
+
+    assert_true(prof_strstr("BoothJ5", "boothj5",               FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("BoothJ5", "boothj5 hello",         FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("BoothJ5", "hello boothj5",         FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("BoothJ5", "hello boothj5 there",   FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("BoothJ5", "helloboothj5test",      FALSE, FALSE) == TRUE);
+
+    assert_true(prof_strstr("boothj5", "BoothJ5",               TRUE, FALSE) == FALSE);
+    assert_true(prof_strstr("boothj5", "BoothJ5 hello",         TRUE, FALSE) == FALSE);
+    assert_true(prof_strstr("boothj5", "hello BoothJ5",         TRUE, FALSE) == FALSE);
+    assert_true(prof_strstr("boothj5", "hello BoothJ5 there",   TRUE, FALSE) == FALSE);
+    assert_true(prof_strstr("boothj5", "helloBoothJ5test",      TRUE, FALSE) == FALSE);
+
+    assert_true(prof_strstr("BoothJ5", "boothj5",               TRUE, FALSE) == FALSE);
+    assert_true(prof_strstr("BoothJ5", "boothj5 hello",         TRUE, FALSE) == FALSE);
+    assert_true(prof_strstr("BoothJ5", "hello boothj5",         TRUE, FALSE) == FALSE);
+    assert_true(prof_strstr("BoothJ5", "hello boothj5 there",   TRUE, FALSE) == FALSE);
+    assert_true(prof_strstr("BoothJ5", "helloboothj5test",      TRUE, FALSE) == FALSE);
+
+    assert_true(prof_strstr("boothj5", "boothj5",               FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "boothj5 hello",         FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "hello boothj5",         FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "hello boothj5 there",   FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "boothj5test",           FALSE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "helloboothj5",          FALSE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "helloboothj5test",      FALSE, TRUE) == FALSE);
+
+    assert_true(prof_strstr("boothj5", "BoothJ5",               TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "BoothJ5 hello",         TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "hello BoothJ5",         TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "hello BoothJ5 there",   TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "BoothJ5test",           TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "helloBoothJ5",          TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "helloBoothJ5test",      TRUE, TRUE) == FALSE);
+
+    assert_true(prof_strstr("BoothJ5", "boothj5",               TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("BoothJ5", "boothj5 hello",         TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("BoothJ5", "hello boothj5",         TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("BoothJ5", "hello boothj5 there",   TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("BoothJ5", "boothj5test",           TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("BoothJ5", "helloboothj5",          TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("BoothJ5", "helloboothj5test",      TRUE, TRUE) == FALSE);
+
+    assert_true(prof_strstr("boothj5", "boothj5:",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "boothj5,",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "boothj5-",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", ":boothj5",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", ",boothj5",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "-boothj5",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", ":boothj5:",             FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", ",boothj5,",             FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "-boothj5-",             FALSE, TRUE) == TRUE);
+
+    assert_true(prof_strstr("boothj5", "BoothJ5:",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "BoothJ5,",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "BoothJ5-",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", ":BoothJ5",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", ",BoothJ5",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "-BoothJ5",              FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", ":BoothJ5:",             FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", ",BoothJ5,",             FALSE, TRUE) == TRUE);
+    assert_true(prof_strstr("boothj5", "-BoothJ5-",             FALSE, TRUE) == TRUE);
+
+    assert_true(prof_strstr("boothj5", "BoothJ5:",              TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "BoothJ5,",              TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "BoothJ5-",              TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", ":BoothJ5",              TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", ",BoothJ5",              TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "-BoothJ5",              TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", ":BoothJ5:",             TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", ",BoothJ5,",             TRUE, TRUE) == FALSE);
+    assert_true(prof_strstr("boothj5", "-BoothJ5-",             TRUE, TRUE) == FALSE);
+
+    assert_true(prof_strstr("K", "don't know", FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("K", "don't know", TRUE,  FALSE) == FALSE);
+    assert_true(prof_strstr("K", "don't know", FALSE, TRUE) == FALSE);
+    assert_true(prof_strstr("K", "don't know", TRUE, TRUE) == FALSE);
+
+    assert_true(prof_strstr("K", "don't Know", FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("K", "don't Know", TRUE,  FALSE) == TRUE);
+    assert_true(prof_strstr("K", "don't Know", FALSE, TRUE) == FALSE);
+    assert_true(prof_strstr("K", "don't Know", TRUE, TRUE) == FALSE);
+
+    assert_true(prof_strstr("K", "backwards", FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("K", "backwards", TRUE,  FALSE) == FALSE);
+    assert_true(prof_strstr("K", "backwards", FALSE, TRUE) == FALSE);
+    assert_true(prof_strstr("K", "backwards", TRUE, TRUE) == FALSE);
+
+    assert_true(prof_strstr("K", "BACKWARDS", FALSE, FALSE) == TRUE);
+    assert_true(prof_strstr("K", "BACKWARDS", TRUE,  FALSE) == TRUE);
+    assert_true(prof_strstr("K", "BACKWARDS", FALSE, TRUE) == FALSE);
+    assert_true(prof_strstr("K", "BACKWARDS", TRUE, TRUE) == FALSE);
 }
diff --git a/tests/unittests/test_common.h b/tests/unittests/test_common.h
index 6f3f1698..f0e901a7 100644
--- a/tests/unittests/test_common.h
+++ b/tests/unittests/test_common.h
@@ -64,3 +64,4 @@ void str_contains_str_whole(void **state);
 void str_empty_not_contains_str(void **state);
 void str_not_contains_str_empty(void **state);
 void str_empty_not_contains_str_empty(void **state);
+void prof_strstr_contains(void **state);
diff --git a/tests/unittests/unittests.c b/tests/unittests/unittests.c
index 6b26cb29..8826f2ec 100644
--- a/tests/unittests/unittests.c
+++ b/tests/unittests/unittests.c
@@ -94,14 +94,6 @@ int main(int argc, char* argv[]) {
         unit_test(strip_quotes_strips_first),
         unit_test(strip_quotes_strips_last),
         unit_test(strip_quotes_strips_both),
-        unit_test(str_not_contains_str),
-        unit_test(str_contains_str_at_start),
-        unit_test(str_contains_str_at_end),
-        unit_test(str_contains_str_in_middle),
-        unit_test(str_contains_str_whole),
-        unit_test(str_empty_not_contains_str),
-        unit_test(str_not_contains_str_empty),
-        unit_test(str_empty_not_contains_str_empty),
 
         unit_test(clear_empty),
         unit_test(reset_after_create),
@@ -624,6 +616,8 @@ int main(int argc, char* argv[]) {
         unit_test_setup_teardown(clears_chat_sessions,
             load_preferences,
             close_preferences),
+
+        unit_test(prof_strstr_contains),
     };
 
     return run_tests(all_tests);