Mercurial > pidgin
annotate src/dbus-analyze-functions.py @ 13598:41e40b323dc3
[gaim-migrate @ 15984]
Previously our file transfer dialog showed "time elapsed" as the current
time minus the time when the transfer was added to the ft dialog.
When sending a file, the transfer is added when you offer the file to
the remote user, not when the transfer actually starts. This meant the
"time elapsed" was longer than it should have been, which threw off the
transfer rate.
This should fix that.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 09 Apr 2006 17:38:38 +0000 |
parents | dcfda39ad547 |
children | 9726dbf3d844 |
rev | line source |
---|---|
11146 | 1 import re |
2 import string | |
3 import sys | |
4 | |
5 | |
11331 | 6 # types translated into "int" |
11171 | 7 simpletypes = ["int", "gint", "guint", "gboolean"] |
8 | |
11331 | 9 # List "excluded" contains functions that shouldn't be exported via |
10 # DBus. If you remove a function from this list, please make sure | |
11 # that it does not break "make" with the configure option | |
12 # "--enable-dbus" turned on. | |
13 | |
14 excluded = [\ | |
15 # I don't remember why this function is excluded; something to do | |
16 # with the fact that it takes a (const) GList as a parameter. | |
17 "gaim_presence_add_list", | |
18 | |
19 # These functions are excluded because they involve value of the | |
20 # type GaimConvPlacementFunc, which is a pointer to a function and | |
21 # (currently?) can't be translated into a DBus type. Normally, | |
22 # functions with untranslatable types are skipped, but this script | |
23 # assumes that all non-pointer type names beginning with "Gaim" | |
24 # are enums, which is not true in this case. | |
25 "gaim_conv_placement_add_fnc", | |
26 "gaim_conv_placement_get_fnc", | |
27 "gaim_conv_placement_get_current_func", | |
28 "gaim_conv_placement_set_current_func", | |
29 ] | |
11146 | 30 |
11331 | 31 # This is a list of functions that return a GList* whose elements are |
32 # string, not pointers to objects. Don't put any functions here, it | |
33 # won't work. | |
11187 | 34 stringlists = [] |
11146 | 35 |
36 pointer = "#pointer#" | |
37 myexception = "My Exception" | |
38 | |
39 def ctopascal(name): | |
40 newname = "" | |
41 for word in name.split("_"): | |
42 newname += word.capitalize() | |
43 return newname | |
44 | |
11241 | 45 class Parameter: |
46 def __init__(self, type, name): | |
47 self.name = name | |
48 self.type = type | |
11146 | 49 |
11241 | 50 def fromtokens(tokens, parameternumber = -1): |
11187 | 51 if len(tokens) == 0: |
11146 | 52 raise myexception |
11187 | 53 if (len(tokens) == 1) or (tokens[-1] == pointer): |
11241 | 54 if parameternumber >= 0: |
55 return Parameter(tokens, "param%i" % parameternumber) | |
56 else: | |
57 raise myexception | |
11187 | 58 else: |
11241 | 59 return Parameter(tokens[:-1], tokens[-1]) |
60 | |
61 fromtokens = staticmethod(fromtokens) | |
62 | |
63 class Binding: | |
64 def __init__(self, functiontext, paramtexts): | |
65 self.function = Parameter.fromtokens(functiontext.split()) | |
66 | |
67 if self.function.name in excluded: | |
68 raise myexception | |
69 | |
70 self.params = [] | |
71 for i in range(len(paramtexts)): | |
72 self.params.append(Parameter.fromtokens(paramtexts[i].split(), i)) | |
73 | |
74 self.call = "%s(%s)" % (self.function.name, | |
75 ", ".join([param.name for param in self.params])) | |
76 | |
77 | |
78 def process(self): | |
79 for param in self.params: | |
80 self.processinput(param.type, param.name) | |
81 | |
82 self.processoutput(self.function.type, "RESULT") | |
83 self.flush() | |
84 | |
85 | |
86 def processinput(self, type, name): | |
87 const = False | |
88 if type[0] == "const": | |
89 type = type[1:] | |
90 const = True | |
91 | |
92 if len(type) == 1: | |
93 # simple types (int, gboolean, etc.) and enums | |
94 if (type[0] in simpletypes) or (type[0].startswith("Gaim")): | |
95 return self.inputsimple(type, name) | |
96 | |
97 | |
98 # va_list, replace by NULL | |
99 if type[0] == "va_list": | |
100 return self.inputvalist(type, name) | |
101 | |
102 # pointers ... | |
103 if (len(type) == 2) and (type[1] == pointer): | |
104 # strings | |
105 if type[0] == "char": | |
106 if const: | |
107 return self.inputstring(type, name) | |
108 else: | |
109 raise myexception | |
110 | |
111 elif type[0] == "GHashTable": | |
112 return self.inputhash(type, name) | |
113 | |
114 # known object types are transformed to integer handles | |
115 elif type[0].startswith("Gaim"): | |
116 return self.inputgaimstructure(type, name) | |
117 | |
118 # unknown pointers are always replaced with NULL | |
119 else: | |
120 return self.inputpointer(type, name) | |
121 return | |
122 | |
123 raise myexception | |
124 | |
125 | |
126 def processoutput(self, type, name): | |
127 # the "void" type is simple ... | |
128 if type == ["void"]: | |
129 return self.outputvoid(type, name) | |
130 | |
131 const = False | |
132 if type[0] == "const": | |
133 type = type[1:] | |
134 const = True | |
135 | |
136 # a string | |
137 if type == ["char", pointer]: | |
138 return self.outputstring(type, name, const) | |
139 | |
140 # simple types (ints, booleans, enums, ...) | |
141 if (len(type) == 1) and \ | |
142 ((type[0] in simpletypes) or (type[0].startswith("Gaim"))): | |
143 return self.outputsimple(type, name) | |
144 | |
145 # pointers ... | |
146 if (len(type) == 2) and (type[1] == pointer): | |
147 | |
148 # handles | |
149 if type[0].startswith("Gaim"): | |
150 return self.outputgaimstructure(type, name) | |
151 | |
152 if type[0] in ["GList", "GSList"]: | |
153 return self.outputlist(type, name) | |
154 | |
155 raise myexception | |
156 | |
11146 | 157 |
11241 | 158 class ClientBinding (Binding): |
159 def __init__(self, functiontext, paramtexts, knowntypes, headersonly): | |
160 Binding.__init__(self, functiontext, paramtexts) | |
161 self.knowntypes = knowntypes | |
162 self.headersonly = headersonly | |
163 self.paramshdr = [] | |
164 self.decls = [] | |
165 self.inputparams = [] | |
166 self.outputparams = [] | |
167 self.returncode = [] | |
168 | |
169 def flush(self): | |
170 print "%s %s(%s)" % (self.functiontype, self.function.name, | |
171 ", ".join(self.paramshdr)), | |
172 | |
173 if self.headersonly: | |
174 print ";" | |
175 return | |
176 | |
177 print "{" | |
178 | |
179 for decl in self.decls: | |
180 print decl | |
181 | |
182 print 'dbus_g_proxy_call(gaim_proxy, "%s", NULL,' % ctopascal(self.function.name) | |
183 | |
184 for type_name in self.inputparams: | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
185 print "\t%s, %s, " % type_name, |
11241 | 186 print "G_TYPE_INVALID," |
187 | |
188 for type_name in self.outputparams: | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
189 print "\t%s, &%s, " % type_name, |
11241 | 190 print "G_TYPE_INVALID);" |
191 | |
192 for code in self.returncode: | |
193 print code | |
194 | |
195 print "}\n" | |
196 | |
197 | |
198 def definegaimstructure(self, type): | |
199 if (self.headersonly) and (type[0] not in self.knowntypes): | |
200 print "struct _%s;" % type[0] | |
201 print "typedef struct _%s %s;" % (type[0], type[0]) | |
202 self.knowntypes.append(type[0]) | |
11146 | 203 |
11241 | 204 def inputsimple(self, type, name): |
205 self.paramshdr.append("%s %s" % (type[0], name)) | |
11277 | 206 self.inputparams.append(("G_TYPE_INT", name)) |
11241 | 207 |
208 def inputvalist(self, type, name): | |
11277 | 209 self.paramshdr.append("va_list %s_NULL" % name) |
11241 | 210 |
211 def inputstring(self, type, name): | |
212 self.paramshdr.append("const char *%s" % name) | |
11277 | 213 self.inputparams.append(("G_TYPE_STRING", name)) |
11241 | 214 |
215 def inputgaimstructure(self, type, name): | |
11277 | 216 self.paramshdr.append("const %s *%s" % (type[0], name)) |
217 self.inputparams.append(("G_TYPE_INT", "GPOINTER_TO_INT(%s)" % name)) | |
11241 | 218 self.definegaimstructure(type) |
219 | |
220 def inputpointer(self, type, name): | |
11277 | 221 name += "_NULL" |
222 self.paramshdr.append("const %s *%s" % (type[0], name)) | |
223 self.inputparams.append(("G_TYPE_INT", "0")) | |
11241 | 224 |
225 def inputhash(self, type, name): | |
11277 | 226 self.paramshdr.append("const GHashTable *%s" % name) |
227 self.inputparams.append(('dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)', name)) | |
11241 | 228 |
229 def outputvoid(self, type, name): | |
230 self.functiontype = "void" | |
231 | |
232 def outputstring(self, type, name, const): | |
233 self.functiontype = "char*" | |
234 self.decls.append("char *%s = NULL;" % name) | |
11277 | 235 self.outputparams.append(("G_TYPE_STRING", name)) |
11241 | 236 # self.returncode.append("NULLIFY(%s);" % name) |
237 self.returncode.append("return %s;" % name); | |
238 | |
239 def outputsimple(self, type, name): | |
240 self.functiontype = type[0] | |
241 self.decls.append("%s %s = 0;" % (type[0], name)) | |
11277 | 242 self.outputparams.append(("G_TYPE_INT", name)) |
11241 | 243 self.returncode.append("return %s;" % name); |
244 | |
11277 | 245 # we could add "const" to the return type but this would probably |
246 # be a nuisance | |
11241 | 247 def outputgaimstructure(self, type, name): |
248 name = name + "_ID" | |
249 self.functiontype = "%s*" % type[0] | |
250 self.decls.append("int %s = 0;" % name) | |
11277 | 251 self.outputparams.append(("G_TYPE_INT", "%s" % name)) |
11241 | 252 self.returncode.append("return (%s*) GINT_TO_POINTER(%s);" % (type[0], name)); |
253 self.definegaimstructure(type) | |
254 | |
255 def outputlist(self, type, name): | |
11277 | 256 self.functiontype = "%s*" % type[0] |
257 self.decls.append("GArray *%s;" % name) | |
258 self.outputparams.append(('dbus_g_type_get_collection("GArray", G_TYPE_INT)', name)) | |
259 self.returncode.append("return garray_int_to_%s(%s);" % | |
260 (type[0].lower(), name)); | |
11171 | 261 |
11241 | 262 |
263 class ServerBinding (Binding): | |
264 def __init__(self, functiontext, paramtexts): | |
265 Binding.__init__(self, functiontext, paramtexts) | |
266 self.dparams = "" | |
267 self.cparams = [] | |
268 self.cdecls = [] | |
269 self.ccode = [] | |
270 self.cparamsout = [] | |
271 self.ccodeout = [] | |
272 self.argfunc = "dbus_message_get_args" | |
11146 | 273 |
11241 | 274 def flush(self): |
275 print "static DBusMessage*" | |
276 print "%s_DBUS(DBusMessage *message_DBUS, DBusError *error_DBUS) {" % \ | |
277 self.function.name | |
278 | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
279 print "\tDBusMessage *reply_DBUS;" |
11241 | 280 |
281 for decl in self.cdecls: | |
282 print decl | |
283 | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
284 print "\t%s(message_DBUS, error_DBUS, " % self.argfunc, |
11241 | 285 for param in self.cparams: |
286 print "DBUS_TYPE_%s, &%s," % param, | |
287 print "DBUS_TYPE_INVALID);" | |
288 | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
289 print "\tCHECK_ERROR(error_DBUS);" |
11241 | 290 |
291 for code in self.ccode: | |
292 print code | |
293 | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
294 print "\treply_DBUS = dbus_message_new_method_return (message_DBUS);" |
11241 | 295 |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
296 print "\tdbus_message_append_args(reply_DBUS, ", |
11241 | 297 for param in self.cparamsout: |
298 if type(param) is str: | |
299 print "%s, " % param | |
300 else: | |
301 print "DBUS_TYPE_%s, &%s, " % param, | |
302 print "DBUS_TYPE_INVALID);" | |
303 | |
304 for code in self.ccodeout: | |
305 print code | |
306 | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
307 print "\treturn reply_DBUS;\n}\n" |
11241 | 308 |
309 | |
310 def addstring(self, *items): | |
311 for item in items: | |
312 self.dparams += item + r"\0" | |
313 | |
314 def addintype(self, type, name): | |
315 self.addstring("in", type, name) | |
316 | |
317 def addouttype(self, type, name): | |
318 self.addstring("out", type, name) | |
11171 | 319 |
11146 | 320 |
11241 | 321 # input parameters |
11146 | 322 |
11241 | 323 def inputsimple(self, type, name): |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
324 self.cdecls.append("\tdbus_int32_t %s;" % name) |
11241 | 325 self.cparams.append(("INT32", name)) |
326 self.addintype("i", name) | |
327 | |
328 def inputvalist(self, type, name): | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
329 self.cdecls.append("\tvoid * %s;" % name); |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
330 self.ccode.append("\t%s = NULL;" % name); |
11241 | 331 |
332 def inputstring(self, type, name): | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
333 self.cdecls.append("\tconst char *%s;" % name) |
11241 | 334 self.cparams.append(("STRING", name)) |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
335 self.ccode .append("\tNULLIFY(%s);" % name) |
11241 | 336 self.addintype("s", name) |
337 | |
338 def inputhash(self, type, name): | |
339 self.argfunc = "gaim_dbus_message_get_args" | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
340 self.cdecls.append("\tDBusMessageIter %s_ITER;" % name) |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
341 self.cdecls.append("\tGHashTable *%s;" % name) |
11241 | 342 self.cparams.append(("ARRAY", "%s_ITER" % name)) |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
343 self.ccode.append("\t%s = gaim_dbus_iter_hash_table(&%s_ITER, error_DBUS);" \ |
11241 | 344 % (name, name)) |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
345 self.ccode.append("\tCHECK_ERROR(error_DBUS);") |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
346 self.ccodeout.append("\tg_hash_table_destroy(%s);" % name) |
11241 | 347 self.addintype("a{ss}", name) |
348 | |
349 def inputgaimstructure(self, type, name): | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
350 self.cdecls.append("\tdbus_int32_t %s_ID;" % name) |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
351 self.cdecls.append("\t%s *%s;" % (type[0], name)) |
11241 | 352 self.cparams.append(("INT32", name + "_ID")) |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
353 self.ccode.append("\tGAIM_DBUS_ID_TO_POINTER(%s, %s_ID, %s, error_DBUS);" % \ |
11241 | 354 (name, name, type[0])) |
355 self.addintype("i", name) | |
356 | |
357 def inputpointer(self, type, name): | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
358 self.cdecls.append("\tdbus_int32_t %s_NULL;" % name) |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
359 self.cdecls .append("\t%s *%s;" % (type[0], name)) |
11241 | 360 self.cparams.append(("INT32", name + "_NULL")) |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
361 self.ccode .append("\t%s = NULL;" % name) |
11241 | 362 self.addintype("i", name) |
363 | |
364 # output parameters | |
365 | |
366 def outputvoid(self, type, name): | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
367 self.ccode.append("\t%s;" % self.call) # just call the function |
11241 | 368 |
369 def outputstring(self, type, name, const): | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
370 self.cdecls.append("\tconst char *%s;" % name) |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
371 self.ccode.append("\t%s = null_to_empty(%s);" % (name, self.call)) |
11241 | 372 self.cparamsout.append(("STRING", name)) |
373 self.addouttype("s", name) | |
374 if not const: | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
375 self.ccodeout.append("\tg_free(%s);" % name) |
11241 | 376 |
377 def outputsimple(self, type, name): | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
378 self.cdecls.append("\tdbus_int32_t %s;" % name) |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
379 self.ccode.append("\t%s = %s;" % (name, self.call)) |
11241 | 380 self.cparamsout.append(("INT32", name)) |
381 self.addouttype("i", name) | |
382 | |
383 def outputgaimstructure(self, type, name): | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
384 self.cdecls.append("\tdbus_int32_t %s;" % name) |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
385 self.ccode .append("\tGAIM_DBUS_POINTER_TO_ID(%s, %s, error_DBUS);" % (name, self.call)) |
11241 | 386 self.cparamsout.append(("INT32", name)) |
387 self.addouttype("i", name) | |
388 | |
389 # GList*, GSList*, assume that list is a list of objects | |
390 | |
391 # fixme: at the moment, we do NOT free the memory occupied by | |
392 # the list, we should free it if the list has NOT been declared const | |
393 | |
394 # fixme: we assume that this is a list of objects, not a list | |
395 # of strings | |
396 | |
397 def outputlist(self, type, name): | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
398 self.cdecls.append("\tdbus_int32_t %s_LEN;" % name) |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
399 self.ccodeout.append("\tg_free(%s);" % name) |
11241 | 400 |
401 if self.function.name in stringlists: | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
402 self.cdecls.append("\tchar **%s;" % name) |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
403 self.ccode.append("\t%s = gaim_%s_to_array(%s, FALSE, &%s_LEN);" % \ |
11241 | 404 (name, type[0], self.call, name)) |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
405 self.cparamsout.append("\tDBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &%s, %s_LEN" \ |
11241 | 406 % (name, name)) |
407 self.addouttype("as", name) | |
408 else: | |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
409 self.cdecls.append("\tdbus_int32_t *%s;" % name) |
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
410 self.ccode.append("\t%s = gaim_dbusify_%s(%s, FALSE, &%s_LEN);" % \ |
11241 | 411 (name, type[0], self.call, name)) |
13591
dcfda39ad547
[gaim-migrate @ 15977]
Etan Reisner <pidgin@unreliablesource.net>
parents:
12627
diff
changeset
|
412 self.cparamsout.append("\tDBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &%s, %s_LEN" \ |
11241 | 413 % (name, name)) |
414 self.addouttype("ai", name) | |
415 | |
416 | |
417 class BindingSet: | |
418 regexp = r"^(\w[^()]*)\(([^()]*)\)\s*;\s*$"; | |
11171 | 419 |
11241 | 420 def __init__(self, inputfile, fprefix): |
421 self.inputiter = iter(inputfile) | |
422 self.functionregexp = \ | |
423 re.compile("^%s(\w[^()]*)\(([^()]*)\)\s*;\s*$" % fprefix) | |
424 | |
425 | |
426 | |
427 def process(self): | |
428 print "/* Generated by %s. Do not edit! */" % sys.argv[0] | |
429 | |
430 for line in self.inputiter: | |
431 words = line.split() | |
432 if len(words) == 0: # empty line | |
433 continue | |
434 if line[0] == "#": # preprocessor directive | |
435 continue | |
436 if words[0] in ["typedef", "struct", "enum", "static"]: | |
437 continue | |
438 | |
439 # accumulate lines until the parentheses are balance or an | |
440 # empty line has been encountered | |
441 myline = line.strip() | |
442 while myline.count("(") > myline.count(")"): | |
443 newline = self.inputiter.next().strip() | |
444 if len(newline) == 0: | |
445 break | |
446 myline += " " + newline | |
447 | |
448 # is this a function declaration? | |
449 thematch = self.functionregexp.match( | |
450 myline.replace("*", " " + pointer + " ")) | |
451 | |
452 if thematch is None: | |
453 continue | |
454 | |
455 functiontext = thematch.group(1) | |
456 paramstext = thematch.group(2).strip() | |
457 | |
458 if (paramstext == "void") or (paramstext == ""): | |
459 paramtexts = [] | |
460 else: | |
461 paramtexts = paramstext.split(",") | |
462 | |
463 try: | |
464 self.processfunction(functiontext, paramtexts) | |
465 except myexception: | |
466 sys.stderr.write(myline + "\n") | |
467 except: | |
468 sys.stderr.write(myline + "\n") | |
469 raise | |
470 | |
471 self.flush() | |
472 | |
473 class ServerBindingSet (BindingSet): | |
474 def __init__(self, inputfile, fprefix): | |
475 BindingSet.__init__(self, inputfile, fprefix) | |
476 self.functions = [] | |
477 | |
478 | |
479 def processfunction(self, functiontext, paramtexts): | |
480 binding = ServerBinding(functiontext, paramtexts) | |
481 binding.process() | |
482 self.functions.append((binding.function.name, binding.dparams)) | |
483 | |
484 def flush(self): | |
485 print "static GaimDBusBinding bindings_DBUS[] = { " | |
486 for function, params in self.functions: | |
487 print '{"%s", "%s", %s_DBUS},' % \ | |
488 (ctopascal(function), params, function) | |
489 | |
12627 | 490 print "{NULL, NULL, NULL}" |
11241 | 491 print "};" |
492 | |
493 print "#define GAIM_DBUS_REGISTER_BINDINGS(handle) gaim_dbus_register_bindings(handle, bindings_DBUS)" | |
494 | |
495 class ClientBindingSet (BindingSet): | |
496 def __init__(self, inputfile, fprefix, headersonly): | |
497 BindingSet.__init__(self, inputfile, fprefix) | |
498 self.functions = [] | |
499 self.knowntypes = [] | |
500 self.headersonly = headersonly | |
501 | |
502 def processfunction(self, functiontext, paramtexts): | |
503 binding = ClientBinding(functiontext, paramtexts, self.knowntypes, self.headersonly) | |
504 binding.process() | |
505 | |
506 def flush(self): | |
507 pass | |
508 | |
509 # Main program | |
510 | |
511 options = {} | |
512 | |
513 for arg in sys.argv[1:]: | |
514 if arg[0:2] == "--": | |
515 mylist = arg[2:].split("=",1) | |
516 command = mylist[0] | |
517 if len(mylist) > 1: | |
518 options[command] = mylist[1] | |
519 else: | |
520 options[command] = None | |
11146 | 521 |
11171 | 522 if "export-only" in options: |
523 fprefix = "DBUS_EXPORT\s+" | |
524 else: | |
525 fprefix = "" | |
11146 | 526 |
11277 | 527 sys.stderr.write("%s: Functions not exported:\n" % sys.argv[0]) |
528 | |
11241 | 529 if "client" in options: |
530 bindings = ClientBindingSet(sys.stdin, fprefix, | |
531 options.has_key("headers")) | |
532 else: | |
533 bindings = ServerBindingSet(sys.stdin, fprefix) | |
534 bindings.process() | |
11146 | 535 |
11241 | 536 |
11146 | 537 |
538 |