src/dbus-analyze-functions.py

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

mercurial