changeset 18059:3f3125b91728

Lots of DBus list handling changes. The objective here was to eliminate a handful of warnings about constness with GLists. Fixing this correctly involved a lot more work than I expected. The DBus code now properly frees non-const lists (it was leaking them before). Also, the stringlist code is much improved. Finally, it compiles without warnings.
author Richard Laager <rlaager@wiktel.com>
date Thu, 07 Jun 2007 04:25:54 +0000
parents 4ca97b26a8fb
children 37a0a0f5122c
files libpurple/dbus-analyze-functions.py libpurple/dbus-bindings.h libpurple/dbus-server.c
diffstat 3 files changed, 140 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/dbus-analyze-functions.py	Thu Jun 07 04:22:42 2007 +0000
+++ b/libpurple/dbus-analyze-functions.py	Thu Jun 07 04:25:54 2007 +0000
@@ -33,9 +33,13 @@
     ]
 
 # This is a list of functions that return a GList* whose elements are
-# string, not pointers to objects.  Don't put any functions here, it
-# won't work.
-stringlists = []
+# string, not pointers to objects.
+stringlists = [
+    "purple_prefs_get_path_list",
+    "purple_prefs_get_string_list",
+    "purple_uri_list_extract_filenames",
+    "purple_uri_list_extract_uris",
+]
 
 pointer = "#pointer#"
 myexception = "My Exception"
@@ -148,7 +152,7 @@
                 return self.outputpurplestructure(type, name)
 
             if type[0] in ["GList", "GSList"]:
-                return self.outputlist(type, name)
+                return self.outputlist(type, name, const)
 
         raise myexception
     
@@ -250,7 +254,7 @@
         self.returncode.append("return (%s*) GINT_TO_POINTER(%s);" % (type[0], name));
         self.definepurplestructure(type)
 
-    def outputlist(self, type, name):
+    def outputlist(self, type, name, const):
         self.functiontype = "%s*" % type[0]
         self.decls.append("GArray *%s;" % name)
         self.outputparams.append(('dbus_g_type_get_collection("GArray", G_TYPE_INT)', name))
@@ -385,28 +389,40 @@
         self.addouttype("i", name)
 
     # GList*, GSList*, assume that list is a list of objects
-
-    # fixme: at the moment, we do NOT free the memory occupied by
-    # the list, we should free it if the list has NOT been declared const
-
-    # fixme: we assume that this is a list of objects, not a list
-    # of strings
-
-    def outputlist(self, type, name):
+    # unless the function is in stringlists
+    def outputlist(self, type, name, const):
         self.cdecls.append("\tdbus_int32_t %s_LEN;" % name)
         self.ccodeout.append("\tg_free(%s);" % name)
 
+        if const:
+            const_prefix = "const_"
+        else:
+            const_prefix = ""
+
+        if (const):
+            self.cdecls.append("\tconst %s *list;" % type[0]);
+        else:
+            self.cdecls.append("\t%s *list;" % type[0]);
+
         if self.function.name in stringlists:
             self.cdecls.append("\tchar **%s;" % name)
-            self.ccode.append("\t%s = purple_%s_to_array(%s, FALSE, &%s_LEN);" % \
-                         (name, type[0], self.call, name))
+            self.ccode.append("\tlist = %s;" % self.call)
+            self.ccode.append("\t%s = (char **)purple_const_%s_to_array(list, &%s_LEN);" % \
+                         (name, type[0], name))
             self.cparamsout.append("\tDBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &%s, %s_LEN" \
                           % (name, name))
+            if (not const):
+                type_name = type[0].lower()[1:]
+                self.ccodeout.append("\tg_%s_foreach(list, (GFunc)g_free, NULL);" % type_name)
+                self.ccodeout.append("\tg_%s_free(list);" % type_name)
             self.addouttype("as", name)
         else:
             self.cdecls.append("\tdbus_int32_t *%s;" % name)
-            self.ccode.append("\t%s = purple_dbusify_%s(%s, FALSE, &%s_LEN);" % \
-                         (name, type[0], self.call, name))
+            self.ccode.append("\tlist = %s;" % self.call)
+            self.ccode.append("\t%s = purple_dbusify_const_%s(list, &%s_LEN);" % \
+                         (name, type[0], name))
+            if (not const):
+                self.ccode.append("\tg_%s_free(list);" % type[0].lower()[1:])
             self.cparamsout.append("\tDBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &%s, %s_LEN" \
                               % (name, name))
             self.addouttype("ai", name)
--- a/libpurple/dbus-bindings.h	Thu Jun 07 04:22:42 2007 +0000
+++ b/libpurple/dbus-bindings.h	Thu Jun 07 04:25:54 2007 +0000
@@ -83,14 +83,52 @@
 					int              first_arg_type,
 					va_list          var_args);
 
+/**
+ * @deprecated In 3.0.0, this method will have a signature and behavior
+ *             like that of purple_dbusify_const_GList().
+ */
 dbus_int32_t* purple_dbusify_GList(GList *list, gboolean free_memory, 
 				 dbus_int32_t *len);
+/**
+ * @deprecated In 3.0.0, this method will have a signature and behavior
+ *             like that of purple_dbusify_const_GSList().
+ */
 dbus_int32_t* purple_dbusify_GSList(GSList *list, gboolean free_memory,
 				  dbus_int32_t *len);
+
+/**
+ * @since 2.1.0
+ */
+dbus_int32_t* purple_dbusify_const_GList(const GList *list, dbus_int32_t *len);
+
+/**
+ * @since 2.1.0
+ */
+dbus_int32_t* purple_dbusify_const_GSList(const GSList *list, dbus_int32_t *len);
+
+/**
+ * @deprecated In 3.0.0, this method will have a signature and behavior
+ *             like that of purple_const_GList_to_array().
+ */
 gpointer* purple_GList_to_array(GList *list, gboolean free_memory,
 			      dbus_int32_t *len);
+/**
+ * @deprecated In 3.0.0, this method will have a signature and behavior
+ *             like that of purple_const_GSList_to_array().
+ */
 gpointer* purple_GSList_to_array(GSList *list, gboolean free_memory,
 			      dbus_int32_t *len);
+
+/**
+ * @since 2.1.0
+ */
+gpointer* purple_const_GList_to_array(const GList *list, dbus_int32_t *len);
+
+/**
+ * @since 2.1.0
+ */
+gpointer* purple_const_GSList_to_array(const GSList *list, dbus_int32_t *len);
+
 GHashTable *purple_dbus_iter_hash_table(DBusMessageIter *iter, DBusError *error);
 
 const char* empty_to_null(const char *str);
--- a/libpurple/dbus-server.c	Thu Jun 07 04:22:42 2007 +0000
+++ b/libpurple/dbus-server.c	Thu Jun 07 04:25:54 2007 +0000
@@ -290,19 +290,45 @@
 }
 
 dbus_int32_t *
-purple_dbusify_GList(GList *list, gboolean free_memory, dbus_int32_t *len)
+purple_dbusify_const_GList(const GList *list, dbus_int32_t *len)
 {
 	dbus_int32_t *array;
 	int i;
-	GList *elem;
+	const GList *elem;
 
-	*len = g_list_length(list);
-	array = g_new0(dbus_int32_t, g_list_length(list));
+	/* g_list_length() should really take a const GList */
+	*len = g_list_length((GList *)list);
+	array = g_new0(dbus_int32_t, *len);
 	for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
 		array[i] = purple_dbus_pointer_to_id(elem->data);
 
-	if (free_memory)
-		g_list_free(list);
+	return array;
+}
+
+dbus_int32_t *
+purple_dbusify_GList(GList *list, gboolean free_memory, dbus_int32_t *len)
+{
+	dbus_int32_t *array = purple_dbusify_const_GList(list, len);
+
+	if (!free_memory)
+		return array;
+
+	g_list_free(list);
+	return array;
+}
+
+dbus_int32_t *
+purple_dbusify_const_GSList(const GSList *list, dbus_int32_t *len)
+{
+	dbus_int32_t *array;
+	int i;
+	const GSList *elem;
+
+	/* g_slist_length should really take a const GSList */
+	*len = g_slist_length((GSList *)list);
+	array = g_new0(dbus_int32_t, *len);
+	for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
+		array[i] = purple_dbus_pointer_to_id(elem->data);
 
 	return array;
 }
@@ -310,17 +336,26 @@
 dbus_int32_t *
 purple_dbusify_GSList(GSList *list, gboolean free_memory, dbus_int32_t *len)
 {
-	dbus_int32_t *array;
-	int i;
-	GSList *elem;
+	dbus_int32_t *array = purple_dbusify_const_GSList(list, len);
+
+	if (!free_memory)
+		return array;
+
+	g_slist_free(list);
+	return array;
+}
 
-	*len = g_slist_length(list);
-	array = g_new0(dbus_int32_t, g_slist_length(list));
+gpointer *
+purple_const_GList_to_array(const GList *list, dbus_int32_t *len)
+{
+	gpointer *array;
+	int i;
+	const GList *elem;
+
+	*len = g_list_length((GList *)list);
+	array = g_new0(gpointer, *len);
 	for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
-		array[i] = purple_dbus_pointer_to_id(elem->data);
-
-	if (free_memory)
-		g_slist_free(list);
+		array[i] = elem->data;
 
 	return array;
 }
@@ -328,36 +363,39 @@
 gpointer *
 purple_GList_to_array(GList *list, gboolean free_memory, dbus_int32_t *len)
 {
+	gpointer *array = purple_const_GList_to_array(list, len);
+
+	if (!free_memory)
+		return array;
+
+	g_list_free(list);
+	return array;
+}
+
+gpointer *
+purple_const_GSList_to_array(const GSList *list, dbus_int32_t *len)
+{
 	gpointer *array;
 	int i;
-	GList *elem;
+	const GSList *elem;
 
-	*len = g_list_length(list);
-	array = g_new0(gpointer, g_list_length(list));
+	*len = g_slist_length((GSList *)list);
+	array = g_new0(gpointer, *len);
 	for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
 		array[i] = elem->data;
 
-	if (free_memory)
-		g_list_free(list);
-
 	return array;
 }
 
 gpointer *
 purple_GSList_to_array(GSList *list, gboolean free_memory, dbus_int32_t *len)
 {
-	gpointer *array;
-	int i;
-	GSList *elem;
+	gpointer *array = purple_const_GSList_to_array(list, len);
 
-	*len = g_slist_length(list);
-	array = g_new0(gpointer, g_slist_length(list));
-	for (i = 0, elem = list; elem != NULL; elem = elem->next, i++)
-		array[i] = elem->data;
+	if (!free_memory)
+		return array;
 
-	if (free_memory)
-		g_slist_free(list);
-
+	g_slist_free(list);
 	return array;
 }