comparison libpurple/dbus-analyze-functions.py @ 18118:ab6d2763b8d8

Re-fix the DBus list handling code by killing const GList* / const GSList* everywhere. Now we maintain a list of functions which return a GList or GSList which must not be freed. Ideally at some point this will be replaced with code that looks at the Doxygen comment for the function and honors @constreturn, which I've declared as a macro around @return that prints a @note about not modifying or freeing the returned value.
author Richard Laager <rlaager@wiktel.com>
date Sat, 16 Jun 2007 19:44:59 +0000
parents cd81f8f36788
children d955d9bd7ea7
comparison
equal deleted inserted replaced
18117:cd81f8f36788 18118:ab6d2763b8d8
30 # as pointer to a struct, instead of a pointer to an enum. This 30 # as pointer to a struct, instead of a pointer to an enum. This
31 # causes a compilation error. Someone should fix this script. 31 # causes a compilation error. Someone should fix this script.
32 "purple_log_read", 32 "purple_log_read",
33 ] 33 ]
34 34
35 # This is a list of functions that return a GList* whose elements are 35 # This is a list of functions that return a GList* or GSList * whose elements
36 # string, not pointers to objects. 36 # are strings, not pointers to objects.
37 stringlists = [ 37 stringlists = [
38 "purple_prefs_get_path_list", 38 "purple_prefs_get_path_list",
39 "purple_prefs_get_string_list", 39 "purple_prefs_get_string_list",
40 "purple_uri_list_extract_filenames", 40 "purple_uri_list_extract_filenames",
41 "purple_uri_list_extract_uris", 41 "purple_uri_list_extract_uris",
42 ]
43
44 # This is a list of functions that return a GList* or GSList* that should
45 # not be freed. Ideally, this information should be obtained from the Doxygen
46 # documentation at some point.
47 constlists = [
48 "purple_account_get_status_types",
49 "purple_accounts_get_all",
50 "purple_account_option_get_list",
51 "purple_connections_get_all",
52 "purple_connections_get_connecting",
53 "purple_get_conversations",
54 "purple_get_ims",
55 "purple_get_chats",
56 "purple_conv_chat_get_users",
57 "purple_conv_chat_get_ignored",
58 "purple_mime_document_get_fields",
59 "purple_mime_document_get_parts",
60 "purple_mime_part_get_fields",
61 "purple_notify_user_info_get_entries",
62 "purple_request_fields_get_required",
63 "purple_request_field_list_get_selected",
64 "purple_request_field_list_get_items",
65 "purple_savedstatuses_get_all",
66 "purple_status_type_get_attrs",
67 "purple_presence_get_statuses",
42 ] 68 ]
43 69
44 pointer = "#pointer#" 70 pointer = "#pointer#"
45 myexception = "My Exception" 71 myexception = "My Exception"
46 72
150 # handles 176 # handles
151 if type[0].startswith("Purple"): 177 if type[0].startswith("Purple"):
152 return self.outputpurplestructure(type, name) 178 return self.outputpurplestructure(type, name)
153 179
154 if type[0] in ["GList", "GSList"]: 180 if type[0] in ["GList", "GSList"]:
155 return self.outputlist(type, name, const) 181 return self.outputlist(type, name)
156 182
157 raise myexception 183 raise myexception
158 184
159 185
160 class ClientBinding (Binding): 186 class ClientBinding (Binding):
252 self.decls.append("int %s = 0;" % name) 278 self.decls.append("int %s = 0;" % name)
253 self.outputparams.append(("G_TYPE_INT", "%s" % name)) 279 self.outputparams.append(("G_TYPE_INT", "%s" % name))
254 self.returncode.append("return (%s*) GINT_TO_POINTER(%s);" % (type[0], name)); 280 self.returncode.append("return (%s*) GINT_TO_POINTER(%s);" % (type[0], name));
255 self.definepurplestructure(type) 281 self.definepurplestructure(type)
256 282
257 def outputlist(self, type, name, const): 283 def outputlist(self, type, name):
258 self.functiontype = "%s*" % type[0] 284 self.functiontype = "%s*" % type[0]
259 self.decls.append("GArray *%s;" % name) 285 self.decls.append("GArray *%s;" % name)
260 self.outputparams.append(('dbus_g_type_get_collection("GArray", G_TYPE_INT)', name)) 286 self.outputparams.append(('dbus_g_type_get_collection("GArray", G_TYPE_INT)', name))
261 self.returncode.append("return garray_int_to_%s(%s);" % 287 self.returncode.append("return garray_int_to_%s(%s);" %
262 (type[0].lower(), name)); 288 (type[0].lower(), name));
388 self.cparamsout.append(("INT32", name)) 414 self.cparamsout.append(("INT32", name))
389 self.addouttype("i", name) 415 self.addouttype("i", name)
390 416
391 # GList*, GSList*, assume that list is a list of objects 417 # GList*, GSList*, assume that list is a list of objects
392 # unless the function is in stringlists 418 # unless the function is in stringlists
393 def outputlist(self, type, name, const): 419 def outputlist(self, type, name):
394 self.cdecls.append("\tdbus_int32_t %s_LEN;" % name) 420 self.cdecls.append("\tdbus_int32_t %s_LEN;" % name)
395 self.ccodeout.append("\tg_free(%s);" % name) 421 self.ccodeout.append("\tg_free(%s);" % name)
396 422
397 if const: 423 self.cdecls.append("\t%s *list;" % type[0]);
398 const_prefix = "const_"
399 else:
400 const_prefix = ""
401
402 if (const):
403 self.cdecls.append("\tconst %s *list;" % type[0]);
404 else:
405 self.cdecls.append("\t%s *list;" % type[0]);
406 424
407 if self.function.name in stringlists: 425 if self.function.name in stringlists:
408 self.cdecls.append("\tchar **%s;" % name) 426 self.cdecls.append("\tchar **%s;" % name)
409 self.ccode.append("\tlist = %s;" % self.call) 427 self.ccode.append("\tlist = %s;" % self.call)
410 self.ccode.append("\t%s = (char **)purple_const_%s_to_array(list, &%s_LEN);" % \ 428 self.ccode.append("\t%s = (char **)purple_%s_to_array(list, FALSE, &%s_LEN);" % \
411 (name, type[0], name)) 429 (name, type[0], name))
412 self.cparamsout.append("DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &%s, %s_LEN" \ 430 self.cparamsout.append("DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &%s, %s_LEN" \
413 % (name, name)) 431 % (name, name))
414 if (not const): 432 if (not (self.function.name in constlists)):
415 type_name = type[0].lower()[1:] 433 type_name = type[0].lower()[1:]
416 self.ccodeout.append("\tg_%s_foreach(list, (GFunc)g_free, NULL);" % type_name) 434 self.ccodeout.append("\tg_%s_foreach(list, (GFunc)g_free, NULL);" % type_name)
417 self.ccodeout.append("\tg_%s_free(list);" % type_name) 435 self.ccodeout.append("\tg_%s_free(list);" % type_name)
418 self.addouttype("as", name) 436 self.addouttype("as", name)
419 else: 437 else:
420 self.cdecls.append("\tdbus_int32_t *%s;" % name) 438 self.cdecls.append("\tdbus_int32_t *%s;" % name)
421 self.ccode.append("\tlist = %s;" % self.call) 439 self.ccode.append("\tlist = %s;" % self.call)
422 self.ccode.append("\t%s = purple_dbusify_const_%s(list, &%s_LEN);" % \ 440 self.ccode.append("\t%s = purple_dbusify_%s(list, FALSE, &%s_LEN);" % \
423 (name, type[0], name)) 441 (name, type[0], name))
424 if (not const): 442 if (not (self.function.name in constlists)):
425 self.ccode.append("\tg_%s_free(list);" % type[0].lower()[1:]) 443 self.ccode.append("\tg_%s_free(list);" % type[0].lower()[1:])
426 self.cparamsout.append("DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &%s, %s_LEN" \ 444 self.cparamsout.append("DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &%s, %s_LEN" \
427 % (name, name)) 445 % (name, name))
428 self.addouttype("ai", name) 446 self.addouttype("ai", name)
429 447