Sat, 16 Nov 2019 13:37:56 +0300
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 */