comparison src/dbus-analyze-functions.py @ 11171:ebb02ea3c789

[gaim-migrate @ 13272] Moved DBUS init call from gtkmain.c to core.c Reimplemented DBUS bindings mechamism to use low-level GLib bindings as described in my last blog entry. This way plugins can add new DBUS methods on the fly. Also wrote an example plugin that demonstrate how to do it. committer: Tailor Script <tailor@pidgin.im>
author Piotr Zielinski <zielaj>
date Sat, 30 Jul 2005 00:23:21 +0000
parents 1c5398ccbeb0
children 57af14280b5f
comparison
equal deleted inserted replaced
11170:0e9e2b923d09 11171:ebb02ea3c789
8 8
9 import re 9 import re
10 import string 10 import string
11 import sys 11 import sys
12 12
13 # mode: "c" or "xml" 13 options = {}
14
15 mode = None
16 14
17 for arg in sys.argv[1:]: 15 for arg in sys.argv[1:]:
18 if arg.startswith("--mode="): 16 if arg[0:2] == "--":
19 mode = arg[len("--mode="):] 17 mylist = arg[2:].split("=",1)
18 command = mylist[0]
19 if len(mylist) > 1:
20 options[command] = mylist[1]
21 else:
22 options[command] = None
20 23
21 # list of object types 24 # list of object types
22 25
23 objecttypes = [] 26 # objecttypes = []
24 27
25 for objecttype in file("dbus-auto-structs.txt"): 28 # for objecttype in file("dbus-auto-structs.txt"):
26 objecttypes.append(objecttype.strip()) 29 # objecttypes.append(objecttype.strip())
27 30
28 # a dictionary of simple types 31 # a dictionary of simple types
29 # each TYPE maps into a pair (dbus-type-name, compatible-c-type-name) 32 # each TYPE maps into a pair (dbus-type-name, compatible-c-type-name)
30 # if compatible-c-type-name is None then it is the same as TYPE 33 # if compatible-c-type-name is None then it is the same as TYPE
31 34
32 simpletypes = { 35 # simpletypes = {
33 "int" : ("i", None), 36 # "int" : ("i", None),
34 "gint" : ("i", None), 37 # "gint" : ("i", None),
35 "guint" : ("u", None), 38 # "guint" : ("u", None),
36 "gboolean" : ("i", "int") 39 # "gboolean" : ("i", "int")
37 } 40 # }
38 41
39 for enum in file("dbus-auto-enums.txt"): 42 simpletypes = ["int", "gint", "guint", "gboolean"]
40 simpletypes[enum.strip()] = ("i", "int") 43
44 # for enum in file("dbus-auto-enums.txt"):
45 # simpletypes[enum.strip()] = ("i", "int")
41 46
42 # functions that shouldn't be exported 47 # functions that shouldn't be exported
43 48
44 excluded = ["gaim_accounts_load", "gaim_account_set_presence"] 49 excluded = ["gaim_accounts_load", "gaim_account_set_presence",
50 "gaim_conv_placement_get_fnc_id", "gaim_conv_placement_add_fnc"]
45 51
46 pointer = "#pointer#" 52 pointer = "#pointer#"
47 prefix = "gaim_object_" 53
54 functions = []
48 55
49 cparams = [] 56 cparams = []
57 cparamsout = []
50 cdecls = [] 58 cdecls = []
51 ccode = [] 59 ccode = []
52 dargs = [] 60 ccodeout = []
53 61
54 myexception = "My Exception" 62 myexception = "My Exception"
55
56 63
57 def ctopascal(name): 64 def ctopascal(name):
58 newname = "" 65 newname = ""
59 for word in name.split("_"): 66 for word in name.split("_"):
60 newname += word.capitalize() 67 newname += word.capitalize()
61 return newname 68 return newname
62 69
63 def dbus_print(function):
64 print '<method name="%s">' % ctopascal(function)
65
66 for name, type, direction in dargs:
67 print '<arg type="%s" name="%s" direction="%s" />' % \
68 (type, name, direction)
69
70 print '</method>'
71 print
72
73 def dbus_clear():
74 global dargs
75 dargs = []
76
77 def c_print(function): 70 def c_print(function):
78 print "static gboolean %s%s(GaimObject *gaim_object," % (prefix, function), 71 print "static DBusMessage *%s_DBUS(DBusMessage *message_DBUS, DBusError *error_DBUS) {" \
79 72 % function
80 for param in cparams: 73
81 print "%s," % param, 74 print "DBusMessage *reply_DBUS;"
82
83 print "GError **error) {"
84 75
85 for decl in cdecls: 76 for decl in cdecls:
86 print decl 77 print decl
87 78
79 print "dbus_message_get_args(message_DBUS, error_DBUS, ",
80 for param in cparams:
81 print "DBUS_TYPE_%s, &%s," % param,
82 print "DBUS_TYPE_INVALID);"
83
84 print "CHECK_ERROR(error_DBUS);"
85
88 for code in ccode: 86 for code in ccode:
89 print code 87 print code
90 88
91 print "return TRUE;\n}\n" 89 print "reply_DBUS = dbus_message_new_method_return (message_DBUS);"
92 90
91 print "dbus_message_append_args(reply_DBUS, ",
92 for param in cparamsout:
93 if type(param) is str:
94 print "%s, " % param
95 else:
96 print "DBUS_TYPE_%s, &%s, " % param,
97 print "DBUS_TYPE_INVALID);"
98
99 for code in ccodeout:
100 print code
101
102 print "return reply_DBUS;\n}\n"
103
104 functions.append(function)
105
93 def c_clear(): 106 def c_clear():
94 global cparams, cdecls, ccode 107 global cparams, cdecls, ccode, cparamsout, ccodeout
95 cparams = [] 108 cparams = []
96 cdecls = [] 109 cdecls = []
97 ccode = [] 110 ccode = []
98 111 cparamsout = []
112 ccodeout = []
113
114
115 def printdispatchtable():
116 print "static GaimDBusBinding bindings_DBUS[] = { "
117 for function in functions:
118 print '{"%s", %s_DBUS},' % (ctopascal(function), function)
119 print "{NULL, NULL}"
120 print "};"
121
122 print "#define GAIM_DBUS_REGISTER_BINDINGS(handle) gaim_dbus_register_bindings(handle, bindings_DBUS)"
99 123
100 # processing an input parameter 124 # processing an input parameter
101 125
102 def inputvar(mytype, name): 126 def inputvar(mytype, name):
103 global dargs, ccode, cparams, cdecls 127 global ccode, cparams, cdecls
104 const = False 128 const = False
105 if mytype[0] == "const": 129 if mytype[0] == "const":
106 mytype = mytype[1:] 130 mytype = mytype[1:]
107 const = True 131 const = True
108 132
109 # simple types (int, gboolean, etc.) and enums 133 # simple types (int, gboolean, etc.) and enums
110 if (len(mytype) == 1) and (mytype[0] in simpletypes): 134 if (len(mytype) == 1) and \
111 dbustype, ctype = simpletypes[mytype[0]] 135 ((mytype[0] in simpletypes) or (mytype[0].startswith("Gaim"))):
112 dargs.append((name, dbustype, "in")) 136 cdecls.append("dbus_int32_t %s;" % name)
113 if ctype is None: 137 cparams.append(("INT32", name))
114 cparams.append(mytype[0] + " " + name)
115 else:
116 cparams.append(ctype + " " + name + "_ORIG")
117 cdecls .append("%s %s;\n" % (mytype[0], name))
118 ccode .append("%s = (%s) %s_ORIG;\n" % \
119 (name, mytype[0], name))
120 return 138 return
121 139
122 # pointers ... 140 # pointers ...
123 141
124 if (len(mytype) == 2) and (mytype[1] == pointer): 142 if (len(mytype) == 2) and (mytype[1] == pointer):
125 # strings 143 # strings
126 if mytype[0] == "char": 144 if mytype[0] == "char":
127 if const: 145 if const:
128 dargs .append((name, "s", "in")) 146 cdecls.append("const char *%s;" % name)
129 cparams.append("const char *" + name) 147 cparams.append(("STRING", name))
130 ccode .append("NULLIFY(%s);" % name) 148 ccode .append("NULLIFY(%s);" % name)
131 return 149 return
132 else: 150 else:
133 raise myexception 151 raise myexception
134 152
135 # known object types are transformed to integer handles 153 # known object types are transformed to integer handles
136 elif mytype[0] in objecttypes: 154 elif mytype[0].startswith("Gaim"):
137 dargs .append((name, "i", "in")) 155 cdecls.append("dbus_int32_t %s_ID;" % name)
138 cparams.append("int " + name + "_ID") 156 cdecls.append("%s *%s;" % (mytype[0], name))
139 cdecls .append("%s *%s;" % (mytype[0], name)) 157 cparams.append(("INT32", name + "_ID"))
140 ccode .append("GAIM_DBUS_ID_TO_POINTER(%s, %s_ID, %s);" % \ 158 ccode.append("GAIM_DBUS_ID_TO_POINTER(%s, %s_ID, %s, error_DBUS);" % \
141 (name, name, mytype[0])) 159 (name, name, mytype[0]))
142 return 160 return
143 161
144 # unknown pointers are always replaced with NULL 162 # unknown pointers are always replaced with NULL
145 else: 163 else:
146 dargs .append((name, "i", "in")) 164 cdecls.append("dbus_int32_t %s_NULL;" % name)
147 cparams.append("int " + name + "_NULL")
148 cdecls .append("%s *%s;" % (mytype[0], name)) 165 cdecls .append("%s *%s;" % (mytype[0], name))
166 cparams.append(("INT32", name + "_NULL"))
149 ccode .append("%s = NULL;" % name) 167 ccode .append("%s = NULL;" % name)
150 return 168 return
151 169
152 raise myexception 170 raise myexception
153 171
161 ccode.append("%s;" % call) # just call the function 179 ccode.append("%s;" % call) # just call the function
162 return 180 return
163 181
164 # a constant string 182 # a constant string
165 if mytype == ["const", "char", pointer]: 183 if mytype == ["const", "char", pointer]:
166 dargs .append((name, "s", "out")) 184 cdecls.append("const char *%s;" % name)
167 cparams.append("char **%s" % name) 185 ccode.append("%s = null_to_empty(%s);" % (name, call))
168 ccode .append("*%s = g_strdup(null_to_empty(%s));" % (name, call)) 186 cparamsout.append(("STRING", name))
169 return 187 return
170 188
171 # simple types (ints, booleans, enums, ...) 189 # simple types (ints, booleans, enums, ...)
172 if (len(mytype) == 1) and (mytype[0] in simpletypes): 190 if (len(mytype) == 1) and \
173 dbustype, ctype = simpletypes[mytype[0]] 191 ((mytype[0] in simpletypes) or (mytype[0].startswith("Gaim"))):
174 192 cdecls.append("dbus_int32_t %s;" % name)
175 if ctype is None: 193 ccode.append("%s = %s;" % (name, call))
176 ctype = mytype[0] 194 cparamsout.append(("INT32", name))
177
178 dargs .append((name, dbustype, "out"))
179 ccode .append("*%s = %s;" % (name, call))
180 cparams.append("%s *%s" % (ctype, name))
181 return 195 return
182 196
183 # pointers ... 197 # pointers ...
184 if (len(mytype) == 2) and (mytype[1] == pointer): 198 if (len(mytype) == 2) and (mytype[1] == pointer):
185 199
186 # handles 200 # handles
187 if mytype[0] in objecttypes: 201 if mytype[0].startswith("Gaim"):
188 dargs .append((name, "i", "out")) 202 cdecls.append("dbus_int32_t %s;" % name)
189 cparams.append("int *%s" % name) 203 ccode .append("GAIM_DBUS_POINTER_TO_ID(%s, %s, error_DBUS);" % (name, call))
190 ccode .append("GAIM_DBUS_POINTER_TO_ID(*%s, %s);" % (name, call)) 204 cparamsout.append(("INT32", name))
191 return 205 return
192 206
193 # GList*, GSList*, assume that list is a list of objects 207 # GList*, GSList*, assume that list is a list of objects
194 # not a list of strings!!! 208 # not a list of strings!!!
209 # this does NOT release memory occupied by the list
195 if mytype[0] in ["GList", "GSList"]: 210 if mytype[0] in ["GList", "GSList"]:
196 dargs .append((name, "ai", "out")) 211 cdecls.append("dbus_int32_t %s_LEN;" % name)
197 cparams.append("GArray **%s" % name) 212 cdecls.append("dbus_int32_t *%s;" % name)
198 ccode .append("*%s = gaim_dbusify_%s(%s, TRUE);" % \ 213 ccode.append("%s = gaim_dbusify_%s(%s, FALSE, &%s_LEN);" % \
199 (name, mytype[0],call)) 214 (name, mytype[0], call, name))
215 cparamsout.append("DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &%s, %s_LEN" \
216 % (name, name))
217 ccodeout.append("g_free(%s);" % name)
200 return 218 return
201 219
202 raise myexception 220 raise myexception
203 221
204 222
205 223
206 def processfunction(functionparam, paramlist): 224 def processfunction(functionparam, paramlist):
207 dbus_clear()
208 c_clear() 225 c_clear()
209 226
210 ftokens = functionparam.split() 227 ftokens = functionparam.split()
211 functiontype, function = ftokens[:-1], ftokens[-1] 228 functiontype, function = ftokens[:-1], ftokens[-1]
212 229
226 names.append(name) 243 names.append(name)
227 244
228 outputvar(functiontype, "RESULT", 245 outputvar(functiontype, "RESULT",
229 "%s(%s)" % (origfunction, ", ".join(names))) 246 "%s(%s)" % (origfunction, ", ".join(names)))
230 247
231 if mode == "c": 248 c_print(function)
232 c_print(function) 249
233 250
234 if mode == "xml": 251
235 dbus_print(function) 252
236 253 print "/* Generated by %s. Do not edit! */" % sys.argv[0]
237 254
238 if mode == "c": 255
239 print "/* Generated by %s. Do not edit! */" % sys.argv[0] 256
240 257 regexp = r"^(\w[^()]*)\(([^()]*)\)\s*;\s*$";
241 if mode == "xml": 258
242 print "<!-- Generated by %s. Do not edit! -->" % sys.argv[0] 259
243 260 if "export-only" in options:
244 functionregexp = re.compile(r"^(\w[^()]*)\(([^()]*)\)\s*;\s*$") 261 fprefix = "DBUS_EXPORT\s+"
262 else:
263 fprefix = ""
264
265 functionregexp = re.compile("^%s(\w[^()]*)\(([^()]*)\)\s*;\s*$" % fprefix)
245 266
246 inputiter = iter(sys.stdin) 267 inputiter = iter(sys.stdin)
247 268
248 for line in inputiter: 269 for line in inputiter:
249 words = line.split() 270 words = line.split()
284 sys.stderr.write(myline + "\n") 305 sys.stderr.write(myline + "\n")
285 except: 306 except:
286 sys.stderr.write(myline + "\n") 307 sys.stderr.write(myline + "\n")
287 raise 308 raise
288 309
289 310 printdispatchtable()
290 311
291
292