--- a/libpurple/purpletags.c Thu Apr 25 21:09:01 2024 -0500
+++ b/libpurple/purpletags.c Thu Apr 25 21:10:37 2024 -0500
@@ -169,6 +169,22 @@
return g_object_new(PURPLE_TYPE_TAGS, NULL);
+purple_tags_exists(PurpleTags *tags, const char *tag) { + g_return_val_if_fail(PURPLE_IS_TAGS(tags), FALSE); + g_return_val_if_fail(!purple_strempty(tag), FALSE); + for(GList *l = tags->tags; l != NULL; l = l->next) { + const char *existing = l->data; + if(purple_strequal(existing, tag)) { purple_tags_lookup(PurpleTags *tags, const gchar *name, gboolean *found) {
@@ -382,3 +398,19 @@
+purple_tags_contains(PurpleTags *tags, PurpleTags *needle) { + g_return_val_if_fail(PURPLE_IS_TAGS(tags), FALSE); + g_return_val_if_fail(PURPLE_IS_TAGS(needle), FALSE); + for(GList *tag = needle->tags; tag != NULL; tag = tag->next) { + const char *needle_tag = tag->data; + if(!purple_tags_exists(tags, needle_tag)) { --- a/libpurple/purpletags.h Thu Apr 25 21:09:01 2024 -0500
+++ b/libpurple/purpletags.h Thu Apr 25 21:10:37 2024 -0500
@@ -43,8 +43,11 @@
* Tags is an object that can be used to keep track of arbitrary tags on
* objects. Tags are simple strings that use the first ':' to delimit a value.
* For example: `foo` is a tag with just a name and no value, but `foo:bar` is
- * a tag with a name and value. Please note this distinction when the API calls
- * for a name versus a tag which would be the name and the value.
+ * a tag with a name and value. Also, `foo:` is still considered a name and + * value, but the value is an empty string. + * Please note this distinction when the API calls for a name versus a tag + * which would be the name and the value. @@ -64,6 +67,22 @@
PurpleTags *purple_tags_new(void);
+ * Checks if @tag exists in @tags. + * This checks both the tag name and value. + * Returns: %TRUE if @tag is in @tags, otherwise %FALSE. +gboolean purple_tags_exists(PurpleTags *tags, const char *tag); * @name: The name of the tag to check if it exists.
@@ -236,6 +255,25 @@
void purple_tag_parse(const char *tag, char **name, char **value);
+ * purple_tags_contains: + * @needle: The tags to find. + * Checks if all of the tags in @needle can be found in @tags. + * This checks tags, which means names and values, and not just tag names. + * For example, if @tags contains `foo:bar, baz`, and @needle contains + * `foo:bar, baz:1` this will return %FALSE because `baz:1` is not in @tags. + * Returns: %TRUE if all tags in @needle can be found in @tags. +gboolean purple_tags_contains(PurpleTags *tags, PurpleTags *needle); #endif /* PURPLE_TAGS_H */
--- a/libpurple/tests/test_tags.c Thu Apr 25 21:09:01 2024 -0500
+++ b/libpurple/tests/test_tags.c Thu Apr 25 21:10:37 2024 -0500
@@ -44,6 +44,25 @@
*****************************************************************************/
+test_purple_tags_exists(void) { + PurpleTags *tags = NULL; + tags = purple_tags_new(); + purple_tags_add(tags, "foo"); + purple_tags_add(tags, "bar:1"); + purple_tags_add(tags, "baz"); + g_assert_true(purple_tags_exists(tags, "foo")); + g_assert_true(purple_tags_exists(tags, "bar:1")); + g_assert_false(purple_tags_exists(tags, "baz:")); + g_assert_false(purple_tags_exists(tags, "qux")); + g_assert_finalize_object(tags); test_purple_tags_lookup_exists(void) {
@@ -560,6 +579,65 @@
purple_tag_parse("", NULL, NULL);
+test_purple_tag_contains_full(void) { + PurpleTags *tags = NULL; + PurpleTags *needle = NULL; + tags = purple_tags_new(); + purple_tags_add(tags, "foo"); + purple_tags_add(tags, "bar:"); + purple_tags_add(tags, "baz:1"); + needle = purple_tags_new(); + purple_tags_add(needle, "foo"); + purple_tags_add(needle, "bar:"); + purple_tags_add(needle, "baz:1"); + g_assert_true(purple_tags_contains(tags, needle)); + g_assert_finalize_object(tags); + g_assert_finalize_object(needle); +test_purple_tag_contains_partial(void) { + PurpleTags *tags = NULL; + PurpleTags *needle = NULL; + tags = purple_tags_new(); + purple_tags_add(tags, "foo"); + purple_tags_add(tags, "bar:"); + purple_tags_add(tags, "baz:1"); + needle = purple_tags_new(); + purple_tags_add(needle, "foo"); + purple_tags_add(needle, "baz:1"); + g_assert_true(purple_tags_contains(tags, needle)); + g_assert_finalize_object(tags); + g_assert_finalize_object(needle); +test_purple_tag_contains_none(void) { + PurpleTags *tags = NULL; + PurpleTags *needle = NULL; + tags = purple_tags_new(); + purple_tags_add(tags, "foo"); + purple_tags_add(tags, "bar:1"); + needle = purple_tags_new(); + purple_tags_add(needle, "baz:qux"); + g_assert_false(purple_tags_contains(tags, needle)); + g_assert_finalize_object(tags); + g_assert_finalize_object(needle); /******************************************************************************
*****************************************************************************/
@@ -567,6 +645,8 @@
main(gint argc, gchar **argv) {
g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/tags/exists", test_purple_tags_exists); g_test_add_func("/tags/lookup-exists", test_purple_tags_lookup_exists);
g_test_add_func("/tags/lookup-non-existent",
test_purple_tags_lookup_non_existent);
@@ -616,5 +696,9 @@
g_test_add_func("/tag/parse", test_purple_tag_parse);
+ g_test_add_func("/tag/contains/full", test_purple_tag_contains_full); + g_test_add_func("/tag/contains/partial", test_purple_tag_contains_partial); + g_test_add_func("/tag/contains/none", test_purple_tag_contains_none);