Changeset View
Changeset View
Standalone View
Standalone View
tools/glib-gtypes-generator.py
Show All 17 Lines | |||||
18 | # | 18 | # | ||
19 | # You should have received a copy of the GNU Lesser General Public | 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 | 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 | 21 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
22 | 22 | | |||
23 | import sys | 23 | import sys | ||
24 | import xml.dom.minidom | 24 | import xml.dom.minidom | ||
25 | 25 | | |||
26 | from libtpcodegen import file_set_contents, u | ||||
26 | from libglibcodegen import escape_as_identifier, \ | 27 | from libglibcodegen import escape_as_identifier, \ | ||
27 | get_docstring, \ | 28 | get_docstring, \ | ||
28 | NS_TP, \ | 29 | NS_TP, \ | ||
29 | Signature, \ | 30 | Signature, \ | ||
30 | type_to_gtype, \ | 31 | type_to_gtype, \ | ||
31 | xml_escape | 32 | xml_escape | ||
32 | 33 | | |||
33 | 34 | | |||
34 | def types_to_gtypes(types): | 35 | def types_to_gtypes(types): | ||
35 | return [type_to_gtype(t)[1] for t in types] | 36 | return [type_to_gtype(t)[1] for t in types] | ||
36 | 37 | | |||
37 | 38 | | |||
38 | class GTypesGenerator(object): | 39 | class GTypesGenerator(object): | ||
39 | def __init__(self, dom, output, mixed_case_prefix): | 40 | def __init__(self, dom, output, mixed_case_prefix): | ||
40 | self.dom = dom | 41 | self.dom = dom | ||
41 | self.Prefix = mixed_case_prefix | 42 | self.Prefix = mixed_case_prefix | ||
42 | self.PREFIX_ = self.Prefix.upper() + '_' | 43 | self.PREFIX_ = self.Prefix.upper() + '_' | ||
43 | self.prefix_ = self.Prefix.lower() + '_' | 44 | self.prefix_ = self.Prefix.lower() + '_' | ||
44 | 45 | | |||
45 | self.header = open(output + '.h', 'w') | 46 | self.header = [] | ||
46 | self.body = open(output + '-body.h', 'w') | 47 | self.body = [] | ||
48 | self.docs = [] | ||||
49 | self.output = output | ||||
47 | 50 | | |||
48 | for f in (self.header, self.body): | 51 | for f in (self.header, self.body, self.docs): | ||
49 | f.write('/* Auto-generated, do not edit.\n *\n' | 52 | f.append('/* Auto-generated, do not edit.\n *\n' | ||
50 | ' * This file may be distributed under the same terms\n' | 53 | ' * This file may be distributed under the same terms\n' | ||
51 | ' * as the specification from which it was generated.\n' | 54 | ' * as the specification from which it was generated.\n' | ||
52 | ' */\n\n') | 55 | ' */\n\n') | ||
53 | 56 | | |||
54 | # keys are e.g. 'sv', values are the key escaped | 57 | # keys are e.g. 'sv', values are the key escaped | ||
55 | self.need_mappings = {} | 58 | self.need_mappings = {} | ||
56 | # keys are the contents of the struct (e.g. 'sssu'), values are the | 59 | # keys are the contents of the struct (e.g. 'sssu'), values are the | ||
57 | # key escaped | 60 | # key escaped | ||
58 | self.need_structs = {} | 61 | self.need_structs = {} | ||
59 | # keys are the contents of the struct (e.g. 'sssu'), values are the | 62 | # keys are the contents of the struct (e.g. 'sssu'), values are the | ||
60 | # key escaped | 63 | # key escaped | ||
61 | self.need_struct_arrays = {} | 64 | self.need_struct_arrays = {} | ||
62 | 65 | | |||
63 | # keys are the contents of the array (unlike need_struct_arrays!), | 66 | # keys are the contents of the array (unlike need_struct_arrays!), | ||
64 | # values are the key escaped | 67 | # values are the key escaped | ||
65 | self.need_other_arrays = {} | 68 | self.need_other_arrays = {} | ||
66 | 69 | | |||
67 | def h(self, code): | 70 | def h(self, code): | ||
68 | self.header.write(code.encode("utf-8")) | 71 | self.header.append(code) | ||
69 | 72 | | |||
70 | def c(self, code): | 73 | def c(self, code): | ||
71 | self.body.write(code.encode("utf-8")) | 74 | self.body.append(code) | ||
75 | | ||||
76 | def d(self, code): | ||||
77 | self.docs.append(code) | ||||
72 | 78 | | |||
73 | def do_mapping_header(self, mapping): | 79 | def do_mapping_header(self, mapping): | ||
74 | members = mapping.getElementsByTagNameNS(NS_TP, 'member') | 80 | members = mapping.getElementsByTagNameNS(NS_TP, 'member') | ||
75 | assert len(members) == 2 | 81 | assert len(members) == 2 | ||
76 | 82 | | |||
77 | impl_sig = ''.join([elt.getAttribute('type') | 83 | impl_sig = ''.join([elt.getAttribute('type') | ||
78 | for elt in members]) | 84 | for elt in members]) | ||
79 | 85 | | |||
80 | esc_impl_sig = escape_as_identifier(impl_sig) | 86 | esc_impl_sig = escape_as_identifier(impl_sig) | ||
81 | 87 | | |||
82 | name = (self.PREFIX_ + 'HASH_TYPE_' + | 88 | name = (self.PREFIX_ + 'HASH_TYPE_' + | ||
83 | mapping.getAttribute('name').upper()) | 89 | mapping.getAttribute('name').upper()) | ||
84 | impl = self.prefix_ + 'type_dbus_hash_' + esc_impl_sig | 90 | impl = self.prefix_ + 'type_dbus_hash_' + esc_impl_sig | ||
85 | 91 | | |||
86 | docstring = get_docstring(mapping) or '(Undocumented)' | 92 | docstring = get_docstring(mapping) or '(Undocumented)' | ||
87 | 93 | | |||
88 | self.h('/**\n * %s:\n *\n' % name) | 94 | self.d('/**\n * %s:\n *\n' % name.strip()) | ||
89 | self.h(' * %s\n' % xml_escape(docstring)) | 95 | self.d(' * %s\n' % xml_escape(docstring)) | ||
90 | self.h(' *\n') | 96 | self.d(' *\n') | ||
91 | self.h(' * This macro expands to a call to a function\n') | 97 | self.d(' * This macro expands to a call to a function\n') | ||
92 | self.h(' * that returns the #GType of a #GHashTable\n') | 98 | self.d(' * that returns the #GType of a #GHashTable\n') | ||
93 | self.h(' * appropriate for representing a D-Bus\n') | 99 | self.d(' * appropriate for representing a D-Bus\n') | ||
94 | self.h(' * dictionary of signature\n') | 100 | self.d(' * dictionary of signature\n') | ||
95 | self.h(' * <literal>a{%s}</literal>.\n' % impl_sig) | 101 | self.d(' * <literal>a{%s}</literal>.\n' % impl_sig) | ||
96 | self.h(' *\n') | 102 | self.d(' *\n') | ||
97 | 103 | | |||
98 | key, value = members | 104 | key, value = members | ||
99 | 105 | | |||
100 | self.h(' * Keys (D-Bus type <literal>%s</literal>,\n' | 106 | self.d(' * Keys (D-Bus type <literal>%s</literal>,\n' | ||
101 | % key.getAttribute('type')) | 107 | % key.getAttribute('type')) | ||
102 | tp_type = key.getAttributeNS(NS_TP, 'type') | 108 | tp_type = key.getAttributeNS(NS_TP, 'type') | ||
103 | if tp_type: | 109 | if tp_type: | ||
104 | self.h(' * type <literal>%s</literal>,\n' % tp_type) | 110 | self.d(' * type <literal>%s</literal>,\n' % tp_type) | ||
105 | self.h(' * named <literal>%s</literal>):\n' | 111 | self.d(' * named <literal>%s</literal>):\n' | ||
106 | % key.getAttribute('name')) | 112 | % key.getAttribute('name')) | ||
107 | docstring = get_docstring(key) or '(Undocumented)' | 113 | docstring = get_docstring(key) or '(Undocumented)' | ||
108 | self.h(' * %s\n' % xml_escape(docstring)) | 114 | self.d(' * %s\n' % xml_escape(docstring)) | ||
109 | self.h(' *\n') | 115 | self.d(' *\n') | ||
110 | 116 | | |||
111 | self.h(' * Values (D-Bus type <literal>%s</literal>,\n' | 117 | self.d(' * Values (D-Bus type <literal>%s</literal>,\n' | ||
112 | % value.getAttribute('type')) | 118 | % value.getAttribute('type')) | ||
113 | tp_type = value.getAttributeNS(NS_TP, 'type') | 119 | tp_type = value.getAttributeNS(NS_TP, 'type') | ||
114 | if tp_type: | 120 | if tp_type: | ||
115 | self.h(' * type <literal>%s</literal>,\n' % tp_type) | 121 | self.d(' * type <literal>%s</literal>,\n' % tp_type) | ||
116 | self.h(' * named <literal>%s</literal>):\n' | 122 | self.d(' * named <literal>%s</literal>):\n' | ||
117 | % value.getAttribute('name')) | 123 | % value.getAttribute('name')) | ||
118 | docstring = get_docstring(value) or '(Undocumented)' | 124 | docstring = get_docstring(value) or '(Undocumented)' | ||
119 | self.h(' * %s\n' % xml_escape(docstring)) | 125 | self.d(' * %s\n' % xml_escape(docstring)) | ||
120 | self.h(' *\n') | 126 | self.d(' *\n') | ||
121 | 127 | | |||
122 | self.h(' */\n') | 128 | self.d(' */\n') | ||
123 | 129 | | |||
124 | self.h('#define %s (%s ())\n\n' % (name, impl)) | 130 | self.h('#define %s (%s ())\n\n' % (name, impl)) | ||
125 | self.need_mappings[impl_sig] = esc_impl_sig | 131 | self.need_mappings[impl_sig] = esc_impl_sig | ||
126 | 132 | | |||
127 | array_name = mapping.getAttribute('array-name') | 133 | array_name = mapping.getAttribute('array-name') | ||
128 | if array_name: | 134 | if array_name: | ||
129 | gtype_name = self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper() | 135 | gtype_name = self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper() | ||
130 | contents_sig = 'a{' + impl_sig + '}' | 136 | contents_sig = 'a{' + impl_sig + '}' | ||
131 | esc_contents_sig = escape_as_identifier(contents_sig) | 137 | esc_contents_sig = escape_as_identifier(contents_sig) | ||
132 | impl = self.prefix_ + 'type_dbus_array_of_' + esc_contents_sig | 138 | impl = self.prefix_ + 'type_dbus_array_of_' + esc_contents_sig | ||
133 | self.h('/**\n * %s:\n\n' % gtype_name) | 139 | self.d('/**\n * %s:\n\n' % gtype_name) | ||
134 | self.h(' * Expands to a call to a function\n') | 140 | self.d(' * Expands to a call to a function\n') | ||
135 | self.h(' * that returns the #GType of a #GPtrArray\n') | 141 | self.d(' * that returns the #GType of a #GPtrArray\n') | ||
136 | self.h(' * of #%s.\n' % name) | 142 | self.d(' * of #%s.\n' % name) | ||
137 | self.h(' */\n') | 143 | self.d(' */\n\n') | ||
144 | | ||||
138 | self.h('#define %s (%s ())\n\n' % (gtype_name, impl)) | 145 | self.h('#define %s (%s ())\n\n' % (gtype_name, impl)) | ||
139 | self.need_other_arrays[contents_sig] = esc_contents_sig | 146 | self.need_other_arrays[contents_sig] = esc_contents_sig | ||
140 | 147 | | |||
141 | def do_struct_header(self, struct): | 148 | def do_struct_header(self, struct): | ||
142 | members = struct.getElementsByTagNameNS(NS_TP, 'member') | 149 | members = struct.getElementsByTagNameNS(NS_TP, 'member') | ||
143 | impl_sig = ''.join([elt.getAttribute('type') for elt in members]) | 150 | impl_sig = ''.join([elt.getAttribute('type') for elt in members]) | ||
144 | esc_impl_sig = escape_as_identifier(impl_sig) | 151 | esc_impl_sig = escape_as_identifier(impl_sig) | ||
145 | 152 | | |||
146 | name = (self.PREFIX_ + 'STRUCT_TYPE_' + | 153 | name = (self.PREFIX_ + 'STRUCT_TYPE_' + | ||
147 | struct.getAttribute('name').upper()) | 154 | struct.getAttribute('name').upper()) | ||
148 | impl = self.prefix_ + 'type_dbus_struct_' + esc_impl_sig | 155 | impl = self.prefix_ + 'type_dbus_struct_' + esc_impl_sig | ||
149 | docstring = struct.getElementsByTagNameNS(NS_TP, 'docstring') | 156 | docstring = struct.getElementsByTagNameNS(NS_TP, 'docstring') | ||
150 | if docstring: | 157 | if docstring: | ||
151 | docstring = docstring[0].toprettyxml() | 158 | docstring = docstring[0].toprettyxml() | ||
152 | if docstring.startswith('<tp:docstring>'): | 159 | if docstring.startswith('<tp:docstring>'): | ||
153 | docstring = docstring[14:] | 160 | docstring = docstring[14:] | ||
154 | if docstring.endswith('</tp:docstring>\n'): | 161 | if docstring.endswith('</tp:docstring>\n'): | ||
155 | docstring = docstring[:-16] | 162 | docstring = docstring[:-16] | ||
156 | if docstring.strip() in ('<tp:docstring/>', ''): | 163 | if docstring.strip() in ('<tp:docstring/>', ''): | ||
157 | docstring = '(Undocumented)' | 164 | docstring = '(Undocumented)' | ||
158 | else: | 165 | else: | ||
159 | docstring = '(Undocumented)' | 166 | docstring = '(Undocumented)' | ||
160 | self.h('/**\n * %s:\n\n' % name) | 167 | self.d('/**\n * %s:\n\n' % name) | ||
161 | self.h(' * %s\n' % xml_escape(docstring)) | 168 | self.d(' * %s\n' % xml_escape(docstring)) | ||
162 | self.h(' *\n') | 169 | self.d(' *\n') | ||
163 | self.h(' * This macro expands to a call to a function\n') | 170 | self.d(' * This macro expands to a call to a function\n') | ||
164 | self.h(' * that returns the #GType of a #GValueArray\n') | 171 | self.d(' * that returns the #GType of a #GValueArray\n') | ||
165 | self.h(' * appropriate for representing a D-Bus struct\n') | 172 | self.d(' * appropriate for representing a D-Bus struct\n') | ||
166 | self.h(' * with signature <literal>(%s)</literal>.\n' | 173 | self.d(' * with signature <literal>(%s)</literal>.\n' | ||
167 | % impl_sig) | 174 | % impl_sig) | ||
168 | self.h(' *\n') | 175 | self.d(' *\n') | ||
169 | 176 | | |||
170 | for i, member in enumerate(members): | 177 | for i, member in enumerate(members): | ||
171 | self.h(' * Member %d (D-Bus type ' | 178 | self.d(' * Member %d (D-Bus type ' | ||
172 | '<literal>%s</literal>,\n' | 179 | '<literal>%s</literal>,\n' | ||
173 | % (i, member.getAttribute('type'))) | 180 | % (i, member.getAttribute('type'))) | ||
174 | tp_type = member.getAttributeNS(NS_TP, 'type') | 181 | tp_type = member.getAttributeNS(NS_TP, 'type') | ||
175 | if tp_type: | 182 | if tp_type: | ||
176 | self.h(' * type <literal>%s</literal>,\n' % tp_type) | 183 | self.d(' * type <literal>%s</literal>,\n' % tp_type) | ||
177 | self.h(' * named <literal>%s</literal>):\n' | 184 | self.d(' * named <literal>%s</literal>):\n' | ||
178 | % member.getAttribute('name')) | 185 | % member.getAttribute('name')) | ||
179 | docstring = get_docstring(member) or '(Undocumented)' | 186 | docstring = get_docstring(member) or '(Undocumented)' | ||
180 | self.h(' * %s\n' % xml_escape(docstring)) | 187 | self.d(' * %s\n' % xml_escape(docstring)) | ||
181 | self.h(' *\n') | 188 | self.d(' *\n') | ||
189 | | ||||
190 | self.d(' */\n\n') | ||||
182 | 191 | | |||
183 | self.h(' */\n') | | |||
184 | self.h('#define %s (%s ())\n\n' % (name, impl)) | 192 | self.h('#define %s (%s ())\n\n' % (name, impl)) | ||
185 | 193 | | |||
186 | array_name = struct.getAttribute('array-name') | 194 | array_name = struct.getAttribute('array-name') | ||
187 | if array_name != '': | 195 | if array_name != '': | ||
188 | array_name = (self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper()) | 196 | array_name = (self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper()) | ||
189 | impl = self.prefix_ + 'type_dbus_array_' + esc_impl_sig | 197 | impl = self.prefix_ + 'type_dbus_array_' + esc_impl_sig | ||
190 | self.h('/**\n * %s:\n\n' % array_name) | 198 | self.d('/**\n * %s:\n\n' % array_name) | ||
191 | self.h(' * Expands to a call to a function\n') | 199 | self.d(' * Expands to a call to a function\n') | ||
192 | self.h(' * that returns the #GType of a #GPtrArray\n') | 200 | self.d(' * that returns the #GType of a #GPtrArray\n') | ||
193 | self.h(' * of #%s.\n' % name) | 201 | self.d(' * of #%s.\n' % name) | ||
194 | self.h(' */\n') | 202 | self.d(' */\n\n') | ||
203 | | ||||
195 | self.h('#define %s (%s ())\n\n' % (array_name, impl)) | 204 | self.h('#define %s (%s ())\n\n' % (array_name, impl)) | ||
196 | self.need_struct_arrays[impl_sig] = esc_impl_sig | 205 | self.need_struct_arrays[impl_sig] = esc_impl_sig | ||
197 | 206 | | |||
198 | self.need_structs[impl_sig] = esc_impl_sig | 207 | self.need_structs[impl_sig] = esc_impl_sig | ||
199 | 208 | | |||
200 | def __call__(self): | 209 | def __call__(self): | ||
201 | mappings = self.dom.getElementsByTagNameNS(NS_TP, 'mapping') | 210 | mappings = self.dom.getElementsByTagNameNS(NS_TP, 'mapping') | ||
202 | structs = self.dom.getElementsByTagNameNS(NS_TP, 'struct') | 211 | structs = self.dom.getElementsByTagNameNS(NS_TP, 'struct') | ||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Line(s) | 285 | self.c(' t = dbus_g_type_get_collection (' | |||
278 | '%stype_dbus_array_of_%s ());\n' % | 287 | '%stype_dbus_array_of_%s ());\n' % | ||
279 | (self.prefix_, escape_as_identifier(sig[1:]))) | 288 | (self.prefix_, escape_as_identifier(sig[1:]))) | ||
280 | else: | 289 | else: | ||
281 | raise AssertionError("array of '%s' not supported" % sig) | 290 | raise AssertionError("array of '%s' not supported" % sig) | ||
282 | 291 | | |||
283 | self.c(' return t;\n') | 292 | self.c(' return t;\n') | ||
284 | self.c('}\n\n') | 293 | self.c('}\n\n') | ||
285 | 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 | | ||||
286 | if __name__ == '__main__': | 299 | if __name__ == '__main__': | ||
287 | argv = sys.argv[1:] | 300 | argv = sys.argv[1:] | ||
288 | 301 | | |||
289 | dom = xml.dom.minidom.parse(argv[0]) | 302 | dom = xml.dom.minidom.parse(argv[0]) | ||
290 | 303 | | |||
291 | GTypesGenerator(dom, argv[1], argv[2])() | 304 | GTypesGenerator(dom, argv[1], argv[2])() |