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
|
|
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
|