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.
7 # Copyright (C) 2006, 2007 Collabora Limited
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.
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.
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
24 import xml
.dom
.minidom
26 from libglibcodegen
import escape_as_identifier
, \
34 def types_to_gtypes(types
):
35 return [type_to_gtype(t
)[1] for t
in types
]
38 class GTypesGenerator(object):
39 def __init__(self
, dom
, output
, mixed_case_prefix
):
41 self
.Prefix
= mixed_case_prefix
42 self
.PREFIX_
= self
.Prefix
.upper() + '_'
43 self
.prefix_
= self
.Prefix
.lower() + '_'
45 self
.header
= open(output
+ '.h', 'w')
46 self
.body
= open(output
+ '-body.h', 'w')
48 for f
in (self
.header
, self
.body
):
49 f
.write('/* Auto-generated, do not edit.\n *\n'
50 ' * This file may be distributed under the same terms\n'
51 ' * as the specification from which it was generated.\n'
54 self
.need_mappings
= {}
55 self
.need_structs
= {}
58 def do_mapping_header(self
, mapping
):
59 members
= mapping
.getElementsByTagNameNS(NS_TP
, 'member')
60 assert len(members
) == 2
62 impl_sig
= ''.join([elt
.getAttribute('type')
65 esc_impl_sig
= escape_as_identifier(impl_sig
)
67 name
= (self
.PREFIX_
+ 'HASH_TYPE_' +
68 mapping
.getAttribute('name').upper())
69 impl
= self
.prefix_
+ 'type_dbus_hash_' + esc_impl_sig
71 docstring
= get_docstring(mapping
) or '(Undocumented)'
73 self
.header
.write('/**\n * %s:\n *\n' % name
)
74 self
.header
.write(' * %s\n' % xml_escape(docstring
))
75 self
.header
.write(' *\n')
76 self
.header
.write(' * This macro expands to a call to a function\n')
77 self
.header
.write(' * that returns the #GType of a #GHashTable\n')
78 self
.header
.write(' * appropriate for representing a D-Bus\n')
79 self
.header
.write(' * dictionary of signature\n')
80 self
.header
.write(' * <literal>a{%s}</literal>.\n' % impl_sig
)
81 self
.header
.write(' *\n')
85 self
.header
.write(' * Keys (D-Bus type <literal>%s</literal>,\n'
86 % key
.getAttribute('type'))
87 tp_type
= key
.getAttributeNS(NS_TP
, 'type')
89 self
.header
.write(' * type <literal>%s</literal>,\n' % tp_type
)
90 self
.header
.write(' * named <literal>%s</literal>):\n'
91 % key
.getAttribute('name'))
92 docstring
= get_docstring(key
) or '(Undocumented)'
93 self
.header
.write(' * %s\n' % xml_escape(docstring
))
94 self
.header
.write(' *\n')
96 self
.header
.write(' * Values (D-Bus type <literal>%s</literal>,\n'
97 % value
.getAttribute('type'))
98 tp_type
= value
.getAttributeNS(NS_TP
, 'type')
100 self
.header
.write(' * type <literal>%s</literal>,\n' % tp_type
)
101 self
.header
.write(' * named <literal>%s</literal>):\n'
102 % value
.getAttribute('name'))
103 docstring
= get_docstring(value
) or '(Undocumented)'
104 self
.header
.write(' * %s\n' % xml_escape(docstring
))
105 self
.header
.write(' *\n')
107 self
.header
.write(' */\n')
109 self
.header
.write('#define %s (%s ())\n\n' % (name
, impl
))
110 self
.need_mappings
[impl_sig
] = esc_impl_sig
112 def do_struct_header(self
, struct
):
113 members
= struct
.getElementsByTagNameNS(NS_TP
, 'member')
114 impl_sig
= ''.join([elt
.getAttribute('type') for elt
in members
])
115 esc_impl_sig
= escape_as_identifier(impl_sig
)
117 name
= (self
.PREFIX_
+ 'STRUCT_TYPE_' +
118 struct
.getAttribute('name').upper())
119 impl
= self
.prefix_
+ 'type_dbus_struct_' + esc_impl_sig
120 docstring
= struct
.getElementsByTagNameNS(NS_TP
, 'docstring')
122 docstring
= docstring
[0].toprettyxml()
123 if docstring
.startswith('<tp:docstring>'):
124 docstring
= docstring
[14:]
125 if docstring
.endswith('</tp:docstring>\n'):
126 docstring
= docstring
[:-16]
127 if docstring
.strip() in ('<tp:docstring/>', ''):
128 docstring
= '(Undocumented)'
130 docstring
= '(Undocumented)'
131 self
.header
.write('/**\n * %s:\n\n' % name
)
132 self
.header
.write(' * %s\n' % xml_escape(docstring
))
133 self
.header
.write(' *\n')
134 self
.header
.write(' * This macro expands to a call to a function\n')
135 self
.header
.write(' * that returns the #GType of a #GValueArray\n')
136 self
.header
.write(' * appropriate for representing a D-Bus struct\n')
137 self
.header
.write(' * with signature <literal>(%s)</literal>.\n'
139 self
.header
.write(' *\n')
141 for i
, member
in enumerate(members
):
142 self
.header
.write(' * Member %d (D-Bus type '
143 '<literal>%s</literal>,\n'
144 % (i
, member
.getAttribute('type')))
145 tp_type
= member
.getAttributeNS(NS_TP
, 'type')
147 self
.header
.write(' * type <literal>%s</literal>,\n' % tp_type
)
148 self
.header
.write(' * named <literal>%s</literal>):\n'
149 % member
.getAttribute('name'))
150 docstring
= get_docstring(member
) or '(Undocumented)'
151 self
.header
.write(' * %s\n' % xml_escape(docstring
))
152 self
.header
.write(' *\n')
154 self
.header
.write(' */\n')
155 self
.header
.write('#define %s (%s ())\n\n' % (name
, impl
))
157 array_name
= struct
.getAttribute('array-name')
159 array_name
= (self
.PREFIX_
+ 'ARRAY_TYPE_' + array_name
.upper())
160 impl
= self
.prefix_
+ 'type_dbus_array_' + esc_impl_sig
161 self
.header
.write('/**\n * %s:\n\n' % array_name
)
162 self
.header
.write(' * Expands to a call to a function\n')
163 self
.header
.write(' * that returns the #GType of a #GPtrArray\n')
164 self
.header
.write(' * of #%s.\n' % name
)
165 self
.header
.write(' */\n')
166 self
.header
.write('#define %s (%s ())\n\n' % (array_name
, impl
))
167 self
.need_arrays
[impl_sig
] = esc_impl_sig
169 self
.need_structs
[impl_sig
] = esc_impl_sig
172 mappings
= self
.dom
.getElementsByTagNameNS(NS_TP
, 'mapping')
173 structs
= self
.dom
.getElementsByTagNameNS(NS_TP
, 'struct')
175 for mapping
in mappings
:
176 self
.do_mapping_header(mapping
)
178 for sig
in self
.need_mappings
:
179 self
.header
.write('GType %stype_dbus_hash_%s (void);\n\n' %
180 (self
.prefix_
, self
.need_mappings
[sig
]))
181 self
.body
.write('GType\n%stype_dbus_hash_%s (void)\n{\n' %
182 (self
.prefix_
, self
.need_mappings
[sig
]))
183 self
.body
.write(' static GType t = 0;\n\n')
184 self
.body
.write(' if (G_UNLIKELY (t == 0))\n')
185 # FIXME: translate sig into two GTypes
186 items
= tuple(Signature(sig
))
187 gtypes
= types_to_gtypes(items
)
188 self
.body
.write(' t = dbus_g_type_get_map ("GHashTable", '
189 '%s, %s);\n' % (gtypes
[0], gtypes
[1]))
190 self
.body
.write(' return t;\n')
191 self
.body
.write('}\n\n')
193 for struct
in structs
:
194 self
.do_struct_header(struct
)
196 for sig
in self
.need_structs
:
197 self
.header
.write('GType %stype_dbus_struct_%s (void);\n\n' %
198 (self
.prefix_
, self
.need_structs
[sig
]))
199 self
.body
.write('GType\n%stype_dbus_struct_%s (void)\n{\n' %
200 (self
.prefix_
, self
.need_structs
[sig
]))
201 self
.body
.write(' static GType t = 0;\n\n')
202 self
.body
.write(' if (G_UNLIKELY (t == 0))\n')
203 self
.body
.write(' t = dbus_g_type_get_struct ("GValueArray",\n')
204 items
= tuple(Signature(sig
))
205 gtypes
= types_to_gtypes(items
)
207 self
.body
.write(' %s,\n' % gtype
)
208 self
.body
.write(' G_TYPE_INVALID);\n')
209 self
.body
.write(' return t;\n')
210 self
.body
.write('}\n\n')
212 for sig
in self
.need_arrays
:
213 self
.header
.write('GType %stype_dbus_array_%s (void);\n\n' %
214 (self
.prefix_
, self
.need_structs
[sig
]))
215 self
.body
.write('GType\n%stype_dbus_array_%s (void)\n{\n' %
216 (self
.prefix_
, self
.need_structs
[sig
]))
217 self
.body
.write(' static GType t = 0;\n\n')
218 self
.body
.write(' if (G_UNLIKELY (t == 0))\n')
219 self
.body
.write(' t = dbus_g_type_get_collection ("GPtrArray", '
220 '%stype_dbus_struct_%s ());\n' %
221 (self
.prefix_
, self
.need_structs
[sig
]))
222 self
.body
.write(' return t;\n')
223 self
.body
.write('}\n\n')
225 if __name__
== '__main__':
228 dom
= xml
.dom
.minidom
.parse(argv
[0])
230 GTypesGenerator(dom
, argv
[1], argv
[2])()