gdbus-codegen: Add support for the org.freedesktop.DBus.Deprecated annotation
[platform/upstream/glib.git] / gio / gdbus-codegen / dbustypes.py
1 # -*- Mode: Python -*-
2
3 # GDBus - GLib D-Bus Library
4 #
5 # Copyright (C) 2008-2011 Red Hat, Inc.
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2 of the License, or (at your option) any later version.
11 #
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General
18 # Public License along with this library; if not, write to the
19 # Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 # Boston, MA 02111-1307, USA.
21 #
22 # Author: David Zeuthen <davidz@redhat.com>
23
24 import utils
25
26 class Annotation:
27     def __init__(self, key, value):
28         self.key = key
29         self.value = value
30         self.annotations = []
31
32 class Arg:
33     def __init__(self, name, signature):
34         self.name = name
35         self.signature = signature
36         self.annotations = []
37         self.doc_string = ''
38         self.since = ''
39
40     def post_process(self, interface_prefix, c_namespace, arg_number):
41         if len(self.doc_string) == 0:
42             self.doc_string = utils.lookup_docs(self.annotations)
43         if len(self.since) == 0:
44             self.since = utils.lookup_since(self.annotations)
45
46         if self.name == None:
47             self.name = 'unnamed_arg%d'%arg_number
48         # default to GVariant
49         self.ctype_in_g  = 'GVariant *'
50         self.ctype_in  = 'GVariant *'
51         self.ctype_out = 'GVariant **'
52         self.gtype = 'G_TYPE_VARIANT'
53         self.free_func = 'g_variant_unref'
54         self.format_in = '@' + self.signature
55         self.format_out = '@' + self.signature
56         if not utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
57             if self.signature == 'b':
58                 self.ctype_in_g  = 'gboolean '
59                 self.ctype_in  = 'gboolean '
60                 self.ctype_out = 'gboolean *'
61                 self.gtype = 'G_TYPE_BOOLEAN'
62                 self.free_func = None
63                 self.format_in = 'b'
64                 self.format_out = 'b'
65             elif self.signature == 'y':
66                 self.ctype_in_g  = 'guchar '
67                 self.ctype_in  = 'guchar '
68                 self.ctype_out = 'guchar *'
69                 self.gtype = 'G_TYPE_UCHAR'
70                 self.free_func = None
71                 self.format_in = 'y'
72                 self.format_out = 'y'
73             elif self.signature == 'n':
74                 self.ctype_in_g  = 'gint '
75                 self.ctype_in  = 'gint16 '
76                 self.ctype_out = 'gint16 *'
77                 self.gtype = 'G_TYPE_INT'
78                 self.free_func = None
79                 self.format_in = 'n'
80                 self.format_out = 'n'
81             elif self.signature == 'q':
82                 self.ctype_in_g  = 'guint '
83                 self.ctype_in  = 'guint16 '
84                 self.ctype_out = 'guint16 *'
85                 self.gtype = 'G_TYPE_UINT'
86                 self.free_func = None
87                 self.format_in = 'q'
88                 self.format_out = 'q'
89             elif self.signature == 'i':
90                 self.ctype_in_g  = 'gint '
91                 self.ctype_in  = 'gint '
92                 self.ctype_out = 'gint *'
93                 self.gtype = 'G_TYPE_INT'
94                 self.free_func = None
95                 self.format_in = 'i'
96                 self.format_out = 'i'
97             elif self.signature == 'u':
98                 self.ctype_in_g  = 'guint '
99                 self.ctype_in  = 'guint '
100                 self.ctype_out = 'guint *'
101                 self.gtype = 'G_TYPE_UINT'
102                 self.free_func = None
103                 self.format_in = 'u'
104                 self.format_out = 'u'
105             elif self.signature == 'x':
106                 self.ctype_in_g  = 'gint64 '
107                 self.ctype_in  = 'gint64 '
108                 self.ctype_out = 'gint64 *'
109                 self.gtype = 'G_TYPE_INT64'
110                 self.free_func = None
111                 self.format_in = 'x'
112                 self.format_out = 'x'
113             elif self.signature == 't':
114                 self.ctype_in_g  = 'guint64 '
115                 self.ctype_in  = 'guint64 '
116                 self.ctype_out = 'guint64 *'
117                 self.gtype = 'G_TYPE_UINT64'
118                 self.free_func = None
119                 self.format_in = 't'
120                 self.format_out = 't'
121             elif self.signature == 'd':
122                 self.ctype_in_g  = 'gdouble '
123                 self.ctype_in  = 'gdouble '
124                 self.ctype_out = 'gdouble *'
125                 self.gtype = 'G_TYPE_DOUBLE'
126                 self.free_func = None
127                 self.format_in = 'd'
128                 self.format_out = 'd'
129             elif self.signature == 's':
130                 self.ctype_in_g  = 'const gchar *'
131                 self.ctype_in  = 'const gchar *'
132                 self.ctype_out = 'gchar **'
133                 self.gtype = 'G_TYPE_STRING'
134                 self.free_func = 'g_free'
135                 self.format_in = 's'
136                 self.format_out = 's'
137             elif self.signature == 'o':
138                 self.ctype_in_g  = 'const gchar *'
139                 self.ctype_in  = 'const gchar *'
140                 self.ctype_out = 'gchar **'
141                 self.gtype = 'G_TYPE_STRING'
142                 self.free_func = 'g_free'
143                 self.format_in = 'o'
144                 self.format_out = 'o'
145             elif self.signature == 'g':
146                 self.ctype_in_g  = 'const gchar *'
147                 self.ctype_in  = 'const gchar *'
148                 self.ctype_out = 'gchar **'
149                 self.gtype = 'G_TYPE_STRING'
150                 self.free_func = 'g_free'
151                 self.format_in = 'g'
152                 self.format_out = 'g'
153             elif self.signature == 'ay':
154                 self.ctype_in_g  = 'const gchar *'
155                 self.ctype_in  = 'const gchar *'
156                 self.ctype_out = 'gchar **'
157                 self.gtype = 'G_TYPE_STRING'
158                 self.free_func = 'g_free'
159                 self.format_in = '^ay'
160                 self.format_out = '^ay'
161             elif self.signature == 'as':
162                 self.ctype_in_g  = 'const gchar *const *'
163                 self.ctype_in  = 'const gchar *const *'
164                 self.ctype_out = 'gchar ***'
165                 self.gtype = 'G_TYPE_STRV'
166                 self.free_func = 'g_strfreev'
167                 self.format_in = '^as'
168                 self.format_out = '^as'
169             elif self.signature == 'aay':
170                 self.ctype_in_g  = 'const gchar *const *'
171                 self.ctype_in  = 'const gchar *const *'
172                 self.ctype_out = 'gchar ***'
173                 self.gtype = 'G_TYPE_STRV'
174                 self.free_func = 'g_strfreev'
175                 self.format_in = '^aay'
176                 self.format_out = '^aay'
177
178 class Method:
179     def __init__(self, name):
180         self.name = name
181         self.in_args = []
182         self.out_args = []
183         self.annotations = []
184         self.doc_string = ''
185         self.since = ''
186         self.deprecated = False
187
188     def post_process(self, interface_prefix, c_namespace):
189         if len(self.doc_string) == 0:
190             self.doc_string = utils.lookup_docs(self.annotations)
191         if len(self.since) == 0:
192             self.since = utils.lookup_since(self.annotations)
193
194         name = self.name
195         overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
196         if utils.is_ugly_case(overridden_name):
197             self.name_lower = overridden_name.lower()
198         else:
199             if overridden_name:
200                 name = overridden_name
201             self.name_lower = utils.camel_case_to_uscore(name).lower().replace('-', '_')
202         self.name_hyphen = self.name_lower.replace('_', '-')
203
204         arg_count = 0
205         for a in self.in_args:
206             a.post_process(interface_prefix, c_namespace, arg_count)
207             arg_count += 1
208
209         for a in self.out_args:
210             a.post_process(interface_prefix, c_namespace, arg_count)
211             arg_count += 1
212
213         if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
214             self.deprecated = True
215
216 class Signal:
217     def __init__(self, name):
218         self.name = name
219         self.args = []
220         self.annotations = []
221         self.doc_string = ''
222         self.since = ''
223         self.deprecated = False
224
225     def post_process(self, interface_prefix, c_namespace):
226         if len(self.doc_string) == 0:
227             self.doc_string = utils.lookup_docs(self.annotations)
228         if len(self.since) == 0:
229             self.since = utils.lookup_since(self.annotations)
230
231         name = self.name
232         overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
233         if utils.is_ugly_case(overridden_name):
234             self.name_lower = overridden_name.lower()
235         else:
236             if overridden_name:
237                 name = overridden_name
238             self.name_lower = utils.camel_case_to_uscore(name).lower().replace('-', '_')
239         self.name_hyphen = self.name_lower.replace('_', '-')
240
241         arg_count = 0
242         for a in self.args:
243             a.post_process(interface_prefix, c_namespace, arg_count)
244             arg_count += 1
245
246         if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
247             self.deprecated = True
248
249 class Property:
250     def __init__(self, name, signature, access):
251         self.name = name
252         self.signature = signature
253         self.access = access
254         self.annotations = []
255         self.arg = Arg('value', self.signature)
256         self.arg.annotations = self.annotations
257         self.readable = False
258         self.writable = False
259         if self.access == 'readwrite':
260             self.readable = True
261             self.writable = True
262         elif self.access == 'read':
263             self.readable = True
264         elif self.access == 'write':
265             self.writable = True
266         else:
267             raise RuntimeError('Invalid access type %s'%self.access)
268         self.doc_string = ''
269         self.since = ''
270         self.deprecated = False
271
272     def post_process(self, interface_prefix, c_namespace):
273         if len(self.doc_string) == 0:
274             self.doc_string = utils.lookup_docs(self.annotations)
275         if len(self.since) == 0:
276             self.since = utils.lookup_since(self.annotations)
277
278         name = self.name
279         overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
280         if utils.is_ugly_case(overridden_name):
281             self.name_lower = overridden_name.lower()
282         else:
283             if overridden_name:
284                 name = overridden_name
285             self.name_lower = utils.camel_case_to_uscore(name).lower().replace('-', '_')
286         self.name_hyphen = self.name_lower.replace('_', '-')
287
288         # recalculate arg
289         self.arg.annotations = self.annotations
290         self.arg.post_process(interface_prefix, c_namespace, 0)
291
292         if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
293             self.deprecated = True
294
295 class Interface:
296     def __init__(self, name):
297         self.name = name
298         self.methods = []
299         self.signals = []
300         self.properties = []
301         self.annotations = []
302         self.doc_string = ''
303         self.doc_string_brief = ''
304         self.since = ''
305         self.deprecated = False
306
307     def post_process(self, interface_prefix, c_namespace):
308         if len(self.doc_string) == 0:
309             self.doc_string = utils.lookup_docs(self.annotations)
310         if len(self.doc_string_brief) == 0:
311             self.doc_string_brief = utils.lookup_brief_docs(self.annotations)
312         if len(self.since) == 0:
313             self.since = utils.lookup_since(self.annotations)
314
315         overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
316         if utils.is_ugly_case(overridden_name):
317             name = overridden_name.replace('_', '')
318             name_with_ns = c_namespace + name
319             self.name_without_prefix = name
320             self.camel_name = name_with_ns
321             if len(c_namespace) > 0:
322                 self.ns_upper = utils.camel_case_to_uscore(c_namespace).upper() + '_'
323                 self.name_lower = utils.camel_case_to_uscore(c_namespace) + '_' + overridden_name.lower()
324             else:
325                 self.ns_upper = ''
326                 self.name_lower = overridden_name.lower()
327             self.name_upper = overridden_name.upper()
328
329             #raise RuntimeError('handle Ugly_Case ', overridden_name)
330         else:
331             if overridden_name:
332                 name = overridden_name
333             else:
334                 name = self.name
335                 if name.startswith(interface_prefix):
336                     name = name[len(interface_prefix):]
337             self.name_without_prefix = name
338             name = utils.strip_dots(name)
339             name_with_ns = utils.strip_dots(c_namespace + '.' + name)
340
341             self.camel_name = name_with_ns
342             if len(c_namespace) > 0:
343                 self.ns_upper = utils.camel_case_to_uscore(c_namespace).upper() + '_'
344                 self.name_lower = utils.camel_case_to_uscore(c_namespace) + '_' + utils.camel_case_to_uscore(name)
345             else:
346                 self.ns_upper = ''
347                 self.name_lower = utils.camel_case_to_uscore(name_with_ns)
348             self.name_upper = utils.camel_case_to_uscore(name).upper()
349
350         if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
351             self.deprecated = True
352
353         for m in self.methods:
354             m.post_process(interface_prefix, c_namespace)
355
356         for s in self.signals:
357             s.post_process(interface_prefix, c_namespace)
358
359         for p in self.properties:
360             p.post_process(interface_prefix, c_namespace)