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