11146
|
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
|
11171
|
13 options = {}
|
11146
|
14
|
|
15 for arg in sys.argv[1:]:
|
11171
|
16 if arg[0:2] == "--":
|
|
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
|
11146
|
23
|
|
24 # list of object types
|
|
25
|
11171
|
26 # objecttypes = []
|
11146
|
27
|
11171
|
28 # for objecttype in file("dbus-auto-structs.txt"):
|
|
29 # objecttypes.append(objecttype.strip())
|
11146
|
30
|
|
31 # a dictionary of simple types
|
|
32 # each TYPE maps into a pair (dbus-type-name, compatible-c-type-name)
|
|
33 # if compatible-c-type-name is None then it is the same as TYPE
|
|
34
|
11171
|
35 # simpletypes = {
|
|
36 # "int" : ("i", None),
|
|
37 # "gint" : ("i", None),
|
|
38 # "guint" : ("u", None),
|
|
39 # "gboolean" : ("i", "int")
|
|
40 # }
|
11146
|
41
|
11171
|
42 simpletypes = ["int", "gint", "guint", "gboolean"]
|
|
43
|
|
44 # for enum in file("dbus-auto-enums.txt"):
|
|
45 # simpletypes[enum.strip()] = ("i", "int")
|
11146
|
46
|
|
47 # functions that shouldn't be exported
|
|
48
|
11171
|
49 excluded = ["gaim_accounts_load", "gaim_account_set_presence",
|
|
50 "gaim_conv_placement_get_fnc_id", "gaim_conv_placement_add_fnc"]
|
11146
|
51
|
|
52 pointer = "#pointer#"
|
11171
|
53
|
|
54 functions = []
|
11146
|
55
|
11175
|
56 dparams = ""
|
11146
|
57 cparams = []
|
11171
|
58 cparamsout = []
|
11146
|
59 cdecls = []
|
|
60 ccode = []
|
11171
|
61 ccodeout = []
|
11146
|
62
|
|
63 myexception = "My Exception"
|
|
64
|
|
65 def ctopascal(name):
|
|
66 newname = ""
|
|
67 for word in name.split("_"):
|
|
68 newname += word.capitalize()
|
|
69 return newname
|
|
70
|
11171
|
71 def c_print(function):
|
|
72 print "static DBusMessage *%s_DBUS(DBusMessage *message_DBUS, DBusError *error_DBUS) {" \
|
|
73 % function
|
11146
|
74
|
11171
|
75 print "DBusMessage *reply_DBUS;"
|
11146
|
76
|
|
77 for decl in cdecls:
|
|
78 print decl
|
|
79
|
11171
|
80 print "dbus_message_get_args(message_DBUS, error_DBUS, ",
|
|
81 for param in cparams:
|
|
82 print "DBUS_TYPE_%s, &%s," % param,
|
|
83 print "DBUS_TYPE_INVALID);"
|
|
84
|
|
85 print "CHECK_ERROR(error_DBUS);"
|
|
86
|
11146
|
87 for code in ccode:
|
|
88 print code
|
|
89
|
11171
|
90 print "reply_DBUS = dbus_message_new_method_return (message_DBUS);"
|
|
91
|
|
92 print "dbus_message_append_args(reply_DBUS, ",
|
|
93 for param in cparamsout:
|
|
94 if type(param) is str:
|
|
95 print "%s, " % param
|
|
96 else:
|
|
97 print "DBUS_TYPE_%s, &%s, " % param,
|
|
98 print "DBUS_TYPE_INVALID);"
|
|
99
|
|
100 for code in ccodeout:
|
|
101 print code
|
|
102
|
|
103 print "return reply_DBUS;\n}\n"
|
|
104
|
11175
|
105 functions.append((function, dparams))
|
11171
|
106
|
11146
|
107 def c_clear():
|
11175
|
108 global cparams, cdecls, ccode, cparamsout, ccodeout, dparams
|
|
109 dparams = ""
|
11146
|
110 cparams = []
|
|
111 cdecls = []
|
|
112 ccode = []
|
11171
|
113 cparamsout = []
|
|
114 ccodeout = []
|
11146
|
115
|
|
116
|
11175
|
117 def addstring(*items):
|
|
118 global dparams
|
|
119 for item in items:
|
|
120 dparams += item + r"\0"
|
|
121
|
|
122 def addintype(type, name):
|
|
123 addstring("in", type, name)
|
|
124
|
|
125 def addouttype(type, name):
|
|
126 addstring("out", type, name)
|
|
127
|
11171
|
128 def printdispatchtable():
|
|
129 print "static GaimDBusBinding bindings_DBUS[] = { "
|
11175
|
130 for function, params in functions:
|
|
131 print '{"%s", "%s", %s_DBUS},' % (ctopascal(function), params, function)
|
11171
|
132 print "{NULL, NULL}"
|
|
133 print "};"
|
|
134
|
|
135 print "#define GAIM_DBUS_REGISTER_BINDINGS(handle) gaim_dbus_register_bindings(handle, bindings_DBUS)"
|
|
136
|
11146
|
137 # processing an input parameter
|
|
138
|
|
139 def inputvar(mytype, name):
|
11171
|
140 global ccode, cparams, cdecls
|
11146
|
141 const = False
|
|
142 if mytype[0] == "const":
|
|
143 mytype = mytype[1:]
|
|
144 const = True
|
|
145
|
|
146 # simple types (int, gboolean, etc.) and enums
|
11171
|
147 if (len(mytype) == 1) and \
|
|
148 ((mytype[0] in simpletypes) or (mytype[0].startswith("Gaim"))):
|
|
149 cdecls.append("dbus_int32_t %s;" % name)
|
|
150 cparams.append(("INT32", name))
|
11175
|
151 addintype("i", name)
|
11146
|
152 return
|
|
153
|
|
154 # pointers ...
|
|
155
|
|
156 if (len(mytype) == 2) and (mytype[1] == pointer):
|
|
157 # strings
|
|
158 if mytype[0] == "char":
|
|
159 if const:
|
11171
|
160 cdecls.append("const char *%s;" % name)
|
|
161 cparams.append(("STRING", name))
|
11146
|
162 ccode .append("NULLIFY(%s);" % name)
|
11175
|
163 addintype("s", name)
|
11146
|
164 return
|
|
165 else:
|
|
166 raise myexception
|
|
167
|
|
168 # known object types are transformed to integer handles
|
11171
|
169 elif mytype[0].startswith("Gaim"):
|
|
170 cdecls.append("dbus_int32_t %s_ID;" % name)
|
|
171 cdecls.append("%s *%s;" % (mytype[0], name))
|
|
172 cparams.append(("INT32", name + "_ID"))
|
|
173 ccode.append("GAIM_DBUS_ID_TO_POINTER(%s, %s_ID, %s, error_DBUS);" % \
|
11146
|
174 (name, name, mytype[0]))
|
11175
|
175 addintype("i", name)
|
11146
|
176 return
|
|
177
|
|
178 # unknown pointers are always replaced with NULL
|
|
179 else:
|
11171
|
180 cdecls.append("dbus_int32_t %s_NULL;" % name)
|
11146
|
181 cdecls .append("%s *%s;" % (mytype[0], name))
|
11171
|
182 cparams.append(("INT32", name + "_NULL"))
|
11146
|
183 ccode .append("%s = NULL;" % name)
|
11175
|
184 addintype("i", name)
|
11146
|
185 return
|
|
186
|
|
187 raise myexception
|
|
188
|
|
189
|
|
190
|
|
191 # processing an output parameter
|
|
192
|
|
193 def outputvar(mytype, name, call):
|
|
194 # the "void" type is simple ...
|
|
195 if mytype == ["void"]:
|
|
196 ccode.append("%s;" % call) # just call the function
|
|
197 return
|
|
198
|
|
199 # a constant string
|
|
200 if mytype == ["const", "char", pointer]:
|
11171
|
201 cdecls.append("const char *%s;" % name)
|
|
202 ccode.append("%s = null_to_empty(%s);" % (name, call))
|
|
203 cparamsout.append(("STRING", name))
|
11175
|
204 addouttype("s", name)
|
11146
|
205 return
|
|
206
|
|
207 # simple types (ints, booleans, enums, ...)
|
11171
|
208 if (len(mytype) == 1) and \
|
|
209 ((mytype[0] in simpletypes) or (mytype[0].startswith("Gaim"))):
|
|
210 cdecls.append("dbus_int32_t %s;" % name)
|
|
211 ccode.append("%s = %s;" % (name, call))
|
|
212 cparamsout.append(("INT32", name))
|
11175
|
213 addouttype("i", name)
|
11146
|
214 return
|
|
215
|
|
216 # pointers ...
|
|
217 if (len(mytype) == 2) and (mytype[1] == pointer):
|
|
218
|
|
219 # handles
|
11171
|
220 if mytype[0].startswith("Gaim"):
|
|
221 cdecls.append("dbus_int32_t %s;" % name)
|
|
222 ccode .append("GAIM_DBUS_POINTER_TO_ID(%s, %s, error_DBUS);" % (name, call))
|
|
223 cparamsout.append(("INT32", name))
|
11175
|
224 addouttype("i", name)
|
11146
|
225 return
|
|
226
|
|
227 # GList*, GSList*, assume that list is a list of objects
|
|
228 # not a list of strings!!!
|
11171
|
229 # this does NOT release memory occupied by the list
|
11146
|
230 if mytype[0] in ["GList", "GSList"]:
|
11171
|
231 cdecls.append("dbus_int32_t %s_LEN;" % name)
|
|
232 cdecls.append("dbus_int32_t *%s;" % name)
|
|
233 ccode.append("%s = gaim_dbusify_%s(%s, FALSE, &%s_LEN);" % \
|
|
234 (name, mytype[0], call, name))
|
|
235 cparamsout.append("DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &%s, %s_LEN" \
|
|
236 % (name, name))
|
|
237 ccodeout.append("g_free(%s);" % name)
|
11175
|
238 addouttype("ai", name)
|
11146
|
239 return
|
|
240
|
|
241 raise myexception
|
|
242
|
|
243
|
|
244
|
|
245 def processfunction(functionparam, paramlist):
|
|
246 c_clear()
|
|
247
|
|
248 ftokens = functionparam.split()
|
|
249 functiontype, function = ftokens[:-1], ftokens[-1]
|
|
250
|
|
251 if function in excluded:
|
|
252 return
|
|
253
|
|
254 origfunction = function
|
|
255 function = function.lower()
|
|
256
|
|
257 names = []
|
|
258 for param in paramlist:
|
|
259 tokens = param.split()
|
|
260 if len(tokens) < 2:
|
|
261 raise myexception
|
|
262 type, name = tokens[:-1], tokens[-1]
|
|
263 inputvar(type, name)
|
|
264 names.append(name)
|
|
265
|
|
266 outputvar(functiontype, "RESULT",
|
|
267 "%s(%s)" % (origfunction, ", ".join(names)))
|
|
268
|
11171
|
269 c_print(function)
|
|
270
|
|
271
|
11146
|
272
|
11171
|
273
|
|
274 print "/* Generated by %s. Do not edit! */" % sys.argv[0]
|
|
275
|
11146
|
276
|
|
277
|
11171
|
278 regexp = r"^(\w[^()]*)\(([^()]*)\)\s*;\s*$";
|
|
279
|
11146
|
280
|
11171
|
281 if "export-only" in options:
|
|
282 fprefix = "DBUS_EXPORT\s+"
|
|
283 else:
|
|
284 fprefix = ""
|
|
285
|
|
286 functionregexp = re.compile("^%s(\w[^()]*)\(([^()]*)\)\s*;\s*$" % fprefix)
|
11146
|
287
|
|
288 inputiter = iter(sys.stdin)
|
|
289
|
|
290 for line in inputiter:
|
|
291 words = line.split()
|
|
292 if len(words) == 0: # empty line
|
|
293 continue
|
|
294 if line[0] == "#": # preprocessor directive
|
|
295 continue
|
|
296 if words[0] in ["typedef", "struct", "enum", "static"]:
|
|
297 continue
|
|
298
|
|
299 # accumulate lines until the parentheses are balance or an
|
|
300 # empty line has been encountered
|
|
301 myline = line.strip()
|
|
302 while myline.count("(") > myline.count(")"):
|
|
303 newline = inputiter.next().strip()
|
|
304 if len(newline) == 0:
|
|
305 break
|
|
306 myline += " " + newline
|
|
307
|
|
308 # is this a function declaration?
|
|
309 thematch = functionregexp.match(
|
|
310 myline.replace("*", " " + pointer + " "))
|
|
311
|
|
312 if thematch is None:
|
|
313 continue
|
|
314
|
|
315 function = thematch.group(1)
|
|
316 parameters = thematch.group(2).strip()
|
|
317
|
|
318 if (parameters == "void") or (parameters == ""):
|
|
319 paramlist = []
|
|
320 else:
|
|
321 paramlist = parameters.split(",")
|
|
322
|
|
323 try:
|
|
324 processfunction(function, paramlist)
|
|
325 except myexception:
|
|
326 sys.stderr.write(myline + "\n")
|
|
327 except:
|
|
328 sys.stderr.write(myline + "\n")
|
|
329 raise
|
|
330
|
11171
|
331 printdispatchtable()
|
11146
|
332
|