pidgin/pidgin

Add some new methods to purple tags

9 days ago, Gary Kramlich
b45add2a840c
Parents 258b96f56580
Children bd2da74b9201
Add some new methods to purple tags

* purple_tags_exists is a simplier version of purple_tags_lookup.
* purple_tags_contains makes it easier to find multiple matching tags.

Testing Done:
Ran the unit tests under valgrind and had the turtles check in on things too.

Reviewed at https://reviews.imfreedom.org/r/3143/
--- 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);
}
+gboolean
+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)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
const gchar *
purple_tags_lookup(PurpleTags *tags, const gchar *name, gboolean *found) {
size_t name_len = 0;
@@ -382,3 +398,19 @@
}
}
}
+
+gboolean
+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)) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
--- 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.
*
* Since: 3.0
*/
@@ -64,6 +67,22 @@
PurpleTags *purple_tags_new(void);
/**
+ * purple_tags_exists:
+ * @tags: The instance.
+ * @tag: The tag data.
+ *
+ * Checks if @tag exists in @tags.
+ *
+ * This checks both the tag name and value.
+ *
+ * Returns: %TRUE if @tag is in @tags, otherwise %FALSE.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+gboolean purple_tags_exists(PurpleTags *tags, const char *tag);
+
+/**
* purple_tags_lookup:
* @tags: The instance.
* @name: The name of the tag to check if it exists.
@@ -236,6 +255,25 @@
PURPLE_AVAILABLE_IN_3_0
void purple_tag_parse(const char *tag, char **name, char **value);
+/**
+ * purple_tags_contains:
+ * @tags: The instance.
+ * @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.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+gboolean purple_tags_contains(PurpleTags *tags, PurpleTags *needle);
+
G_END_DECLS
#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 @@
* Tests
*****************************************************************************/
static void
+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);
+}
+
+static void
test_purple_tags_lookup_exists(void) {
PurpleTags *tags = NULL;
gboolean found = FALSE;
@@ -560,6 +579,65 @@
purple_tag_parse("", NULL, NULL);
}
+static void
+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);
+}
+
+static void
+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);
+}
+
+static void
+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);
+}
+
/******************************************************************************
* Public API
*****************************************************************************/
@@ -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);
+
return g_test_run();
}