Add PurpleAttr to use in lists instead of consecutive key and value elements

Sat, 16 Nov 2019 13:37:56 +0300

author
qarkai <qarkai@gmail.com>
date
Sat, 16 Nov 2019 13:37:56 +0300
changeset 40327
4caeb8c0b1ca
parent 40326
cdca03a74387
child 40328
45e719e8d3bc

Add PurpleAttr to use in lists instead of consecutive key and value elements

libpurple/account.c file | annotate | diff | comparison | revisions
libpurple/accounts.c file | annotate | diff | comparison | revisions
libpurple/status.c file | annotate | diff | comparison | revisions
libpurple/status.h file | annotate | diff | comparison | revisions
--- a/libpurple/account.c	Sat Nov 16 13:36:56 2019 +0300
+++ b/libpurple/account.c	Sat Nov 16 13:37:56 2019 +0300
@@ -1793,19 +1793,12 @@
 						gboolean active, ...)
 {
 	GList *attrs = NULL;
-	const gchar *id;
-	gpointer data;
 	va_list args;
 
 	va_start(args, active);
-	while ((id = va_arg(args, const char *)) != NULL)
-	{
-		attrs = g_list_append(attrs, (char *)id);
-		data = va_arg(args, void *);
-		attrs = g_list_append(attrs, data);
-	}
+	attrs = purple_attr_list_from_vargs(args);
 	purple_account_set_status_list(account, status_id, active, attrs);
-	g_list_free(attrs);
+	g_list_free_full(attrs, g_free);
 	va_end(args);
 }
 
--- a/libpurple/accounts.c	Sat Nov 16 13:36:56 2019 +0300
+++ b/libpurple/accounts.c	Sat Nov 16 13:37:56 2019 +0300
@@ -210,6 +210,7 @@
 	for (child = purple_xmlnode_get_child(node, "attribute"); child != NULL;
 			child = purple_xmlnode_get_next_twin(child))
 	{
+		PurpleAttr *attr = NULL;
 		const char *id = purple_xmlnode_get_attrib(child, "id");
 		const char *value = purple_xmlnode_get_attrib(child, "value");
 
@@ -220,26 +221,26 @@
 		if (!attr_value)
 			continue;
 
-		list = g_list_append(list, (char *)id);
-
 		switch (G_VALUE_TYPE(attr_value))
 		{
 			case G_TYPE_STRING:
-				list = g_list_append(list, (char *)value);
+				attr = purple_attr_new(id, (char *)value);
 				break;
 			case G_TYPE_INT:
 			case G_TYPE_BOOLEAN:
 			{
 				int v;
 				if (sscanf(value, "%d", &v) == 1)
-					list = g_list_append(list, GINT_TO_POINTER(v));
-				else
-					list = g_list_remove(list, id);
+					attr = purple_attr_new(id, GINT_TO_POINTER(v));
 				break;
 			}
 			default:
 				break;
 		}
+
+		if (attr != NULL) {
+			list = g_list_append(list, attr);
+		}
 	}
 
 	return list;
@@ -280,7 +281,7 @@
 
 	purple_account_set_status_list(account, type, active, attrs);
 
-	g_list_free(attrs);
+	g_list_free_full(attrs, g_free);
 }
 
 static void
--- a/libpurple/status.c	Sat Nov 16 13:36:56 2019 +0300
+++ b/libpurple/status.c	Sat Nov 16 13:37:56 2019 +0300
@@ -714,18 +714,10 @@
 void
 purple_status_set_active_with_attrs(PurpleStatus *status, gboolean active, va_list args)
 {
-	GList *attrs = NULL;
-	const gchar *id;
-	gpointer data;
+	GList *attrs = purple_attr_list_from_vargs(args);
 
-	while ((id = va_arg(args, const char *)) != NULL)
-	{
-		attrs = g_list_append(attrs, (char *)id);
-		data = va_arg(args, void *);
-		attrs = g_list_append(attrs, data);
-	}
 	purple_status_set_active_with_attrs_list(status, active, attrs);
-	g_list_free(attrs);
+	g_list_free_full(attrs, g_free);
 }
 
 void
@@ -758,58 +750,46 @@
 	priv->active = active;
 
 	/* Set any attributes */
-	l = attrs;
-	while (l != NULL)
+	for (l = attrs; l != NULL; l = l->next)
 	{
-		const gchar *id;
+		PurpleAttr *attr = l->data;
 		GValue *value;
 
-		id = l->data;
-		l = l->next;
-		value = purple_status_get_attr_value(status, id);
+		value = purple_status_get_attr_value(status, attr->id);
 		if (value == NULL)
 		{
 			purple_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is "
-							   "not supported.\n", id, priv->status_type->name);
+							   "not supported.\n", attr->id, priv->status_type->name);
 			/* Skip over the data and move on to the next attribute */
-			l = l->next;
 			continue;
 		}
 
-		specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id);
+		specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)attr->id);
 
 		if (G_VALUE_TYPE(value) == G_TYPE_STRING)
 		{
-			const gchar *string_data = l->data;
-			l = l->next;
+			const gchar *string_data = attr->data;
 			if (purple_strequal(string_data, g_value_get_string(value)))
 				continue;
-			status_set_attr_string(status, id, string_data);
+			status_set_attr_string(status, attr->id, string_data);
 			changed = TRUE;
 		}
 		else if (G_VALUE_TYPE(value) == G_TYPE_INT)
 		{
-			int int_data = GPOINTER_TO_INT(l->data);
-			l = l->next;
+			int int_data = GPOINTER_TO_INT(attr->data);
 			if (int_data == g_value_get_int(value))
 				continue;
-			status_set_attr_int(status, id, int_data);
+			status_set_attr_int(status, attr->id, int_data);
 			changed = TRUE;
 		}
 		else if (G_VALUE_TYPE(value) == G_TYPE_BOOLEAN)
 		{
-			gboolean boolean_data = GPOINTER_TO_INT(l->data);
-			l = l->next;
+			gboolean boolean_data = GPOINTER_TO_INT(attr->data);
 			if (boolean_data == g_value_get_boolean(value))
 				continue;
-			status_set_attr_boolean(status, id, boolean_data);
+			status_set_attr_boolean(status, attr->id, boolean_data);
 			changed = TRUE;
 		}
-		else
-		{
-			/* We don't know what the data is--skip over it */
-			l = l->next;
-		}
 	}
 
 	/* Reset any unspecified attributes to their default value */
@@ -1369,3 +1349,35 @@
 {
 	purple_prefs_disconnect_by_handle(purple_prefs_get_handle());
 }
+
+/**************************************************************************/
+/* PurpleAttr helpers                                                     */
+/**************************************************************************/
+PurpleAttr *
+purple_attr_new(const char *id, gpointer data)
+{
+	PurpleAttr *attr;
+
+	attr = g_new0(PurpleAttr, 1);
+	attr->id = id;
+	attr->data = data;
+
+	return attr;
+}
+
+GList *
+purple_attr_list_from_vargs(va_list args)
+{
+	GList *attrs = NULL;
+	const gchar *id;
+
+	while ((id = va_arg(args, const char *)) != NULL)
+	{
+		gpointer data = va_arg(args, gpointer);
+		PurpleAttr *attr = purple_attr_new(id, data);
+
+		attrs = g_list_append(attrs, attr);
+	}
+
+	return attrs;
+}
--- a/libpurple/status.h	Sat Nov 16 13:36:56 2019 +0300
+++ b/libpurple/status.h	Sat Nov 16 13:37:56 2019 +0300
@@ -96,6 +96,21 @@
 	PURPLE_STATUS_NUM_PRIMITIVES, /*< skip >*/
 } PurpleStatusPrimitive;
 
+/**
+ * PurpleAttr:
+ * @id: The attribute id
+ * @data: The attribute data
+ *
+ * A name-value pair.
+ *
+ * Similar to PurpleKeyValuePair except it doesn't allocate memory for @id and @data.
+ */
+typedef struct _PurpleAttr
+{
+	const gchar *id;
+	gpointer data;
+} PurpleAttr;
+
 #include "presence.h"
 
 #define PURPLE_TUNE_ARTIST	"tune_artist"
@@ -495,7 +510,7 @@
  * purple_status_set_active_with_attrs_list:
  * @status: The status.
  * @active: The active state.
- * @attrs: (element-type void): A list of attributes to set on the status.  This list is
+ * @attrs: (element-type PurpleAttr): A list of attributes to set on the status.  This list is
  *               composed of key/value pairs, where each key is a valid
  *               attribute name for this PurpleStatusType.  The list is
  *               not modified or freed by this function.
@@ -700,6 +715,38 @@
  */
 void purple_statuses_uninit(void);
 
+/**************************************************************************/
+/* PurpleAttr helpers                                                     */
+/**************************************************************************/
+
+/**
+ * purple_attr_new:
+ * @id:  The name part of PurpleAttr
+ * @data:  The value part of PurpleAttr
+ *
+ * Creates a new PurpleAttr.
+ *
+ * Returns:  The created PurpleAttr
+ *
+ * Since: 3.0.0
+ */
+PurpleAttr *purple_attr_new(const char *id, gpointer data);
+
+/**
+ * purple_attr_list_from_vargs:
+ * @args:   A list of attributes to parse.  This list is
+ *               composed of key/value pairs, where each key is a valid
+ *               attribute name for this PurpleStatusType.  The list should
+ *               be NULL terminated.
+ *
+ * Returns a list of attributes constructed from args.
+ *
+ * Returns: (element-type PurpleAttr) (transfer full): The list of attributes.
+ *
+ * Since: 3.0.0
+ */
+GList *purple_attr_list_from_vargs(va_list args);
+
 G_END_DECLS
 
 #endif /* PURPLE_STATUS_H */

mercurial