Mercurial > pidgin
comparison src/dbus-analyze-functions.py @ 11146:1c5398ccbeb0
[gaim-migrate @ 13217]
Gaim-DBUS signal export works with DBUS >= 0.35
Various gaim API functions available through DBUS
committer: Tailor Script <tailor@pidgin.im>
author | Piotr Zielinski <zielaj> |
---|---|
date | Fri, 22 Jul 2005 19:47:29 +0000 |
parents | |
children | ebb02ea3c789 |
comparison
equal
deleted
inserted
replaced
11145:dbc518c453f2 | 11146:1c5398ccbeb0 |
---|---|
1 # This programs takes a C header file as the input and produces: | |
2 # | |
3 # with option --mode=xml: xml dbus specification | |
4 # with option --mode=c: C wrappers | |
5 # | |
6 | |
7 | |
8 | |
9 import re | |
10 import string | |
11 import sys | |
12 | |
13 # mode: "c" or "xml" | |
14 | |
15 mode = None | |
16 | |
17 for arg in sys.argv[1:]: | |
18 if arg.startswith("--mode="): | |
19 mode = arg[len("--mode="):] | |
20 | |
21 # list of object types | |
22 | |
23 objecttypes = [] | |
24 | |
25 for objecttype in file("dbus-auto-structs.txt"): | |
26 objecttypes.append(objecttype.strip()) | |
27 | |
28 # a dictionary of simple types | |
29 # 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 | |
31 | |
32 simpletypes = { | |
33 "int" : ("i", None), | |
34 "gint" : ("i", None), | |
35 "guint" : ("u", None), | |
36 "gboolean" : ("i", "int") | |
37 } | |
38 | |
39 for enum in file("dbus-auto-enums.txt"): | |
40 simpletypes[enum.strip()] = ("i", "int") | |
41 | |
42 # functions that shouldn't be exported | |
43 | |
44 excluded = ["gaim_accounts_load", "gaim_account_set_presence"] | |
45 | |
46 pointer = "#pointer#" | |
47 prefix = "gaim_object_" | |
48 | |
49 cparams = [] | |
50 cdecls = [] | |
51 ccode = [] | |
52 dargs = [] | |
53 | |
54 myexception = "My Exception" | |
55 | |
56 | |
57 def ctopascal(name): | |
58 newname = "" | |
59 for word in name.split("_"): | |
60 newname += word.capitalize() | |
61 return newname | |
62 | |
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): | |
78 print "static gboolean %s%s(GaimObject *gaim_object," % (prefix, function), | |
79 | |
80 for param in cparams: | |
81 print "%s," % param, | |
82 | |
83 print "GError **error) {" | |
84 | |
85 for decl in cdecls: | |
86 print decl | |
87 | |
88 for code in ccode: | |
89 print code | |
90 | |
91 print "return TRUE;\n}\n" | |
92 | |
93 def c_clear(): | |
94 global cparams, cdecls, ccode | |
95 cparams = [] | |
96 cdecls = [] | |
97 ccode = [] | |
98 | |
99 | |
100 # processing an input parameter | |
101 | |
102 def inputvar(mytype, name): | |
103 global dargs, ccode, cparams, cdecls | |
104 const = False | |
105 if mytype[0] == "const": | |
106 mytype = mytype[1:] | |
107 const = True | |
108 | |
109 # simple types (int, gboolean, etc.) and enums | |
110 if (len(mytype) == 1) and (mytype[0] in simpletypes): | |
111 dbustype, ctype = simpletypes[mytype[0]] | |
112 dargs.append((name, dbustype, "in")) | |
113 if ctype is None: | |
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 | |
121 | |
122 # pointers ... | |
123 | |
124 if (len(mytype) == 2) and (mytype[1] == pointer): | |
125 # strings | |
126 if mytype[0] == "char": | |
127 if const: | |
128 dargs .append((name, "s", "in")) | |
129 cparams.append("const char *" + name) | |
130 ccode .append("NULLIFY(%s);" % name) | |
131 return | |
132 else: | |
133 raise myexception | |
134 | |
135 # known object types are transformed to integer handles | |
136 elif mytype[0] in objecttypes: | |
137 dargs .append((name, "i", "in")) | |
138 cparams.append("int " + name + "_ID") | |
139 cdecls .append("%s *%s;" % (mytype[0], name)) | |
140 ccode .append("GAIM_DBUS_ID_TO_POINTER(%s, %s_ID, %s);" % \ | |
141 (name, name, mytype[0])) | |
142 return | |
143 | |
144 # unknown pointers are always replaced with NULL | |
145 else: | |
146 dargs .append((name, "i", "in")) | |
147 cparams.append("int " + name + "_NULL") | |
148 cdecls .append("%s *%s;" % (mytype[0], name)) | |
149 ccode .append("%s = NULL;" % name) | |
150 return | |
151 | |
152 raise myexception | |
153 | |
154 | |
155 | |
156 # processing an output parameter | |
157 | |
158 def outputvar(mytype, name, call): | |
159 # the "void" type is simple ... | |
160 if mytype == ["void"]: | |
161 ccode.append("%s;" % call) # just call the function | |
162 return | |
163 | |
164 # a constant string | |
165 if mytype == ["const", "char", pointer]: | |
166 dargs .append((name, "s", "out")) | |
167 cparams.append("char **%s" % name) | |
168 ccode .append("*%s = g_strdup(null_to_empty(%s));" % (name, call)) | |
169 return | |
170 | |
171 # simple types (ints, booleans, enums, ...) | |
172 if (len(mytype) == 1) and (mytype[0] in simpletypes): | |
173 dbustype, ctype = simpletypes[mytype[0]] | |
174 | |
175 if ctype is None: | |
176 ctype = mytype[0] | |
177 | |
178 dargs .append((name, dbustype, "out")) | |
179 ccode .append("*%s = %s;" % (name, call)) | |
180 cparams.append("%s *%s" % (ctype, name)) | |
181 return | |
182 | |
183 # pointers ... | |
184 if (len(mytype) == 2) and (mytype[1] == pointer): | |
185 | |
186 # handles | |
187 if mytype[0] in objecttypes: | |
188 dargs .append((name, "i", "out")) | |
189 cparams.append("int *%s" % name) | |
190 ccode .append("GAIM_DBUS_POINTER_TO_ID(*%s, %s);" % (name, call)) | |
191 return | |
192 | |
193 # GList*, GSList*, assume that list is a list of objects | |
194 # not a list of strings!!! | |
195 if mytype[0] in ["GList", "GSList"]: | |
196 dargs .append((name, "ai", "out")) | |
197 cparams.append("GArray **%s" % name) | |
198 ccode .append("*%s = gaim_dbusify_%s(%s, TRUE);" % \ | |
199 (name, mytype[0],call)) | |
200 return | |
201 | |
202 raise myexception | |
203 | |
204 | |
205 | |
206 def processfunction(functionparam, paramlist): | |
207 dbus_clear() | |
208 c_clear() | |
209 | |
210 ftokens = functionparam.split() | |
211 functiontype, function = ftokens[:-1], ftokens[-1] | |
212 | |
213 if function in excluded: | |
214 return | |
215 | |
216 origfunction = function | |
217 function = function.lower() | |
218 | |
219 names = [] | |
220 for param in paramlist: | |
221 tokens = param.split() | |
222 if len(tokens) < 2: | |
223 raise myexception | |
224 type, name = tokens[:-1], tokens[-1] | |
225 inputvar(type, name) | |
226 names.append(name) | |
227 | |
228 outputvar(functiontype, "RESULT", | |
229 "%s(%s)" % (origfunction, ", ".join(names))) | |
230 | |
231 if mode == "c": | |
232 c_print(function) | |
233 | |
234 if mode == "xml": | |
235 dbus_print(function) | |
236 | |
237 | |
238 if mode == "c": | |
239 print "/* Generated by %s. Do not edit! */" % sys.argv[0] | |
240 | |
241 if mode == "xml": | |
242 print "<!-- Generated by %s. Do not edit! -->" % sys.argv[0] | |
243 | |
244 functionregexp = re.compile(r"^(\w[^()]*)\(([^()]*)\)\s*;\s*$") | |
245 | |
246 inputiter = iter(sys.stdin) | |
247 | |
248 for line in inputiter: | |
249 words = line.split() | |
250 if len(words) == 0: # empty line | |
251 continue | |
252 if line[0] == "#": # preprocessor directive | |
253 continue | |
254 if words[0] in ["typedef", "struct", "enum", "static"]: | |
255 continue | |
256 | |
257 # accumulate lines until the parentheses are balance or an | |
258 # empty line has been encountered | |
259 myline = line.strip() | |
260 while myline.count("(") > myline.count(")"): | |
261 newline = inputiter.next().strip() | |
262 if len(newline) == 0: | |
263 break | |
264 myline += " " + newline | |
265 | |
266 # is this a function declaration? | |
267 thematch = functionregexp.match( | |
268 myline.replace("*", " " + pointer + " ")) | |
269 | |
270 if thematch is None: | |
271 continue | |
272 | |
273 function = thematch.group(1) | |
274 parameters = thematch.group(2).strip() | |
275 | |
276 if (parameters == "void") or (parameters == ""): | |
277 paramlist = [] | |
278 else: | |
279 paramlist = parameters.split(",") | |
280 | |
281 try: | |
282 processfunction(function, paramlist) | |
283 except myexception: | |
284 sys.stderr.write(myline + "\n") | |
285 except: | |
286 sys.stderr.write(myline + "\n") | |
287 raise | |
288 | |
289 | |
290 | |
291 | |
292 |