]> git.0d.be Git - empathy.git/blob - tools/glib-gtypes-generator.py
Updated Galician translations for docs
[empathy.git] / tools / glib-gtypes-generator.py
1 #!/usr/bin/python
2
3 # Generate GLib GInterfaces from the Telepathy specification.
4 # The master copy of this program is in the telepathy-glib repository -
5 # please make any changes there.
6 #
7 # Copyright (C) 2006, 2007 Collabora Limited
8 #
9 # This library is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public
11 # License as published by the Free Software Foundation; either
12 # version 2.1 of the License, or (at your option) any later version.
13 #
14 # This library is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 # Lesser General Public License for more details.
18 #
19 # You should have received a copy of the GNU Lesser General Public
20 # License along with this library; if not, write to the Free Software
21 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22
23 import sys
24 import xml.dom.minidom
25
26 from libtpcodegen import file_set_contents, u
27 from libglibcodegen import escape_as_identifier, \
28                            get_docstring, \
29                            NS_TP, \
30                            Signature, \
31                            type_to_gtype, \
32                            xml_escape
33
34
35 def types_to_gtypes(types):
36     return [type_to_gtype(t)[1] for t in types]
37
38
39 class GTypesGenerator(object):
40     def __init__(self, dom, output, mixed_case_prefix):
41         self.dom = dom
42         self.Prefix = mixed_case_prefix
43         self.PREFIX_ = self.Prefix.upper() + '_'
44         self.prefix_ = self.Prefix.lower() + '_'
45
46         self.header = []
47         self.body = []
48         self.docs = []
49         self.output = output
50
51         for f in (self.header, self.body, self.docs):
52             f.append('/* Auto-generated, do not edit.\n *\n'
53                      ' * This file may be distributed under the same terms\n'
54                      ' * as the specification from which it was generated.\n'
55                      ' */\n\n')
56
57         # keys are e.g. 'sv', values are the key escaped
58         self.need_mappings = {}
59         # keys are the contents of the struct (e.g. 'sssu'), values are the
60         # key escaped
61         self.need_structs = {}
62         # keys are the contents of the struct (e.g. 'sssu'), values are the
63         # key escaped
64         self.need_struct_arrays = {}
65
66         # keys are the contents of the array (unlike need_struct_arrays!),
67         # values are the key escaped
68         self.need_other_arrays = {}
69
70     def h(self, code):
71         self.header.append(code)
72
73     def c(self, code):
74         self.body.append(code)
75
76     def d(self, code):
77         self.docs.append(code)
78
79     def do_mapping_header(self, mapping):
80         members = mapping.getElementsByTagNameNS(NS_TP, 'member')
81         assert len(members) == 2
82
83         impl_sig = ''.join([elt.getAttribute('type')
84                             for elt in members])
85
86         esc_impl_sig = escape_as_identifier(impl_sig)
87
88         name = (self.PREFIX_ + 'HASH_TYPE_' +
89                 mapping.getAttribute('name').upper())
90         impl = self.prefix_ + 'type_dbus_hash_' + esc_impl_sig
91
92         docstring = get_docstring(mapping) or '(Undocumented)'
93
94         self.d('/**\n * %s:\n *\n' % name.strip())
95         self.d(' * %s\n' % xml_escape(docstring))
96         self.d(' *\n')
97         self.d(' * This macro expands to a call to a function\n')
98         self.d(' * that returns the #GType of a #GHashTable\n')
99         self.d(' * appropriate for representing a D-Bus\n')
100         self.d(' * dictionary of signature\n')
101         self.d(' * <literal>a{%s}</literal>.\n' % impl_sig)
102         self.d(' *\n')
103
104         key, value = members
105
106         self.d(' * Keys (D-Bus type <literal>%s</literal>,\n'
107                           % key.getAttribute('type'))
108         tp_type = key.getAttributeNS(NS_TP, 'type')
109         if tp_type:
110             self.d(' * type <literal>%s</literal>,\n' % tp_type)
111         self.d(' * named <literal>%s</literal>):\n'
112                           % key.getAttribute('name'))
113         docstring = get_docstring(key) or '(Undocumented)'
114         self.d(' * %s\n' % xml_escape(docstring))
115         self.d(' *\n')
116
117         self.d(' * Values (D-Bus type <literal>%s</literal>,\n'
118                           % value.getAttribute('type'))
119         tp_type = value.getAttributeNS(NS_TP, 'type')
120         if tp_type:
121             self.d(' * type <literal>%s</literal>,\n' % tp_type)
122         self.d(' * named <literal>%s</literal>):\n'
123                           % value.getAttribute('name'))
124         docstring = get_docstring(value) or '(Undocumented)'
125         self.d(' * %s\n' % xml_escape(docstring))
126         self.d(' *\n')
127
128         self.d(' */\n')
129
130         self.h('#define %s (%s ())\n\n' % (name, impl))
131         self.need_mappings[impl_sig] = esc_impl_sig
132
133         array_name = mapping.getAttribute('array-name')
134         if array_name:
135             gtype_name = self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper()
136             contents_sig = 'a{' + impl_sig + '}'
137             esc_contents_sig = escape_as_identifier(contents_sig)
138             impl = self.prefix_ + 'type_dbus_array_of_' + esc_contents_sig
139             self.d('/**\n * %s:\n\n' % gtype_name)
140             self.d(' * Expands to a call to a function\n')
141             self.d(' * that returns the #GType of a #GPtrArray\n')
142             self.d(' * of #%s.\n' % name)
143             self.d(' */\n\n')
144
145             self.h('#define %s (%s ())\n\n' % (gtype_name, impl))
146             self.need_other_arrays[contents_sig] = esc_contents_sig
147
148     def do_struct_header(self, struct):
149         members = struct.getElementsByTagNameNS(NS_TP, 'member')
150         impl_sig = ''.join([elt.getAttribute('type') for elt in members])
151         esc_impl_sig = escape_as_identifier(impl_sig)
152
153         name = (self.PREFIX_ + 'STRUCT_TYPE_' +
154                 struct.getAttribute('name').upper())
155         impl = self.prefix_ + 'type_dbus_struct_' + esc_impl_sig
156         docstring = struct.getElementsByTagNameNS(NS_TP, 'docstring')
157         if docstring:
158             docstring = docstring[0].toprettyxml()
159             if docstring.startswith('<tp:docstring>'):
160                 docstring = docstring[14:]
161             if docstring.endswith('</tp:docstring>\n'):
162                 docstring = docstring[:-16]
163             if docstring.strip() in ('<tp:docstring/>', ''):
164                 docstring = '(Undocumented)'
165         else:
166             docstring = '(Undocumented)'
167         self.d('/**\n * %s:\n\n' % name)
168         self.d(' * %s\n' % xml_escape(docstring))
169         self.d(' *\n')
170         self.d(' * This macro expands to a call to a function\n')
171         self.d(' * that returns the #GType of a #GValueArray\n')
172         self.d(' * appropriate for representing a D-Bus struct\n')
173         self.d(' * with signature <literal>(%s)</literal>.\n'
174                           % impl_sig)
175         self.d(' *\n')
176
177         for i, member in enumerate(members):
178             self.d(' * Member %d (D-Bus type '
179                               '<literal>%s</literal>,\n'
180                               % (i, member.getAttribute('type')))
181             tp_type = member.getAttributeNS(NS_TP, 'type')
182             if tp_type:
183                 self.d(' * type <literal>%s</literal>,\n' % tp_type)
184             self.d(' * named <literal>%s</literal>):\n'
185                               % member.getAttribute('name'))
186             docstring = get_docstring(member) or '(Undocumented)'
187             self.d(' * %s\n' % xml_escape(docstring))
188             self.d(' *\n')
189
190         self.d(' */\n\n')
191
192         self.h('#define %s (%s ())\n\n' % (name, impl))
193
194         array_name = struct.getAttribute('array-name')
195         if array_name != '':
196             array_name = (self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper())
197             impl = self.prefix_ + 'type_dbus_array_' + esc_impl_sig
198             self.d('/**\n * %s:\n\n' % array_name)
199             self.d(' * Expands to a call to a function\n')
200             self.d(' * that returns the #GType of a #GPtrArray\n')
201             self.d(' * of #%s.\n' % name)
202             self.d(' */\n\n')
203
204             self.h('#define %s (%s ())\n\n' % (array_name, impl))
205             self.need_struct_arrays[impl_sig] = esc_impl_sig
206
207         self.need_structs[impl_sig] = esc_impl_sig
208
209     def __call__(self):
210         mappings = self.dom.getElementsByTagNameNS(NS_TP, 'mapping')
211         structs = self.dom.getElementsByTagNameNS(NS_TP, 'struct')
212
213         for mapping in mappings:
214             self.do_mapping_header(mapping)
215
216         for sig in self.need_mappings:
217             self.h('GType %stype_dbus_hash_%s (void);\n\n' %
218                               (self.prefix_, self.need_mappings[sig]))
219             self.c('GType\n%stype_dbus_hash_%s (void)\n{\n' %
220                               (self.prefix_, self.need_mappings[sig]))
221             self.c('  static GType t = 0;\n\n')
222             self.c('  if (G_UNLIKELY (t == 0))\n')
223             # FIXME: translate sig into two GTypes
224             items = tuple(Signature(sig))
225             gtypes = types_to_gtypes(items)
226             self.c('    t = dbus_g_type_get_map ("GHashTable", '
227                             '%s, %s);\n' % (gtypes[0], gtypes[1]))
228             self.c('  return t;\n')
229             self.c('}\n\n')
230
231         for struct in structs:
232             self.do_struct_header(struct)
233
234         for sig in self.need_structs:
235             self.h('GType %stype_dbus_struct_%s (void);\n\n' %
236                               (self.prefix_, self.need_structs[sig]))
237             self.c('GType\n%stype_dbus_struct_%s (void)\n{\n' %
238                               (self.prefix_, self.need_structs[sig]))
239             self.c('  static GType t = 0;\n\n')
240             self.c('  if (G_UNLIKELY (t == 0))\n')
241             self.c('    t = dbus_g_type_get_struct ("GValueArray",\n')
242             items = tuple(Signature(sig))
243             gtypes = types_to_gtypes(items)
244             for gtype in gtypes:
245                 self.c('        %s,\n' % gtype)
246             self.c('        G_TYPE_INVALID);\n')
247             self.c('  return t;\n')
248             self.c('}\n\n')
249
250         for sig in self.need_struct_arrays:
251             self.h('GType %stype_dbus_array_%s (void);\n\n' %
252                               (self.prefix_, self.need_struct_arrays[sig]))
253             self.c('GType\n%stype_dbus_array_%s (void)\n{\n' %
254                               (self.prefix_, self.need_struct_arrays[sig]))
255             self.c('  static GType t = 0;\n\n')
256             self.c('  if (G_UNLIKELY (t == 0))\n')
257             self.c('    t = dbus_g_type_get_collection ("GPtrArray", '
258                             '%stype_dbus_struct_%s ());\n' %
259                             (self.prefix_, self.need_struct_arrays[sig]))
260             self.c('  return t;\n')
261             self.c('}\n\n')
262
263         for sig in self.need_other_arrays:
264             self.h('GType %stype_dbus_array_of_%s (void);\n\n' %
265                               (self.prefix_, self.need_other_arrays[sig]))
266             self.c('GType\n%stype_dbus_array_of_%s (void)\n{\n' %
267                               (self.prefix_, self.need_other_arrays[sig]))
268             self.c('  static GType t = 0;\n\n')
269             self.c('  if (G_UNLIKELY (t == 0))\n')
270
271             if sig[:2] == 'a{' and sig[-1:] == '}':
272                 # array of mappings
273                 self.c('    t = dbus_g_type_get_collection ('
274                             '"GPtrArray", '
275                             '%stype_dbus_hash_%s ());\n' %
276                             (self.prefix_, escape_as_identifier(sig[2:-1])))
277             elif sig[:2] == 'a(' and sig[-1:] == ')':
278                 # array of arrays of struct
279                 self.c('    t = dbus_g_type_get_collection ('
280                             '"GPtrArray", '
281                             '%stype_dbus_array_%s ());\n' %
282                             (self.prefix_, escape_as_identifier(sig[2:-1])))
283             elif sig[:1] == 'a':
284                 # array of arrays of non-struct
285                 self.c('    t = dbus_g_type_get_collection ('
286                             '"GPtrArray", '
287                             '%stype_dbus_array_of_%s ());\n' %
288                             (self.prefix_, escape_as_identifier(sig[1:])))
289             else:
290                 raise AssertionError("array of '%s' not supported" % sig)
291
292             self.c('  return t;\n')
293             self.c('}\n\n')
294
295         file_set_contents(self.output + '.h', u('').join(self.header).encode('utf-8'))
296         file_set_contents(self.output + '-body.h', u('').join(self.body).encode('utf-8'))
297         file_set_contents(self.output + '-gtk-doc.h', u('').join(self.docs).encode('utf-8'))
298
299 if __name__ == '__main__':
300     argv = sys.argv[1:]
301
302     dom = xml.dom.minidom.parse(argv[0])
303
304     GTypesGenerator(dom, argv[1], argv[2])()