# HG changeset patch # User Richard Laager # Date 1181190354 0 # Node ID 3f3125b91728a431e477ee6479bb1fca1774b614 # Parent 4ca97b26a8fb06f210430a280573e5b1dea4b744 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. diff -r 4ca97b26a8fb -r 3f3125b91728 libpurple/dbus-analyze-functions.py --- 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) diff -r 4ca97b26a8fb -r 3f3125b91728 libpurple/dbus-bindings.h --- 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); diff -r 4ca97b26a8fb -r 3f3125b91728 libpurple/dbus-server.c --- 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; }