Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : * GObject introspection: IDL generator
3 : : *
4 : : * Copyright (C) 2005 Matthias Clasen
5 : : * Copyright (C) 2008,2009 Red Hat, Inc.
6 : : *
7 : : * SPDX-License-Identifier: LGPL-2.1-or-later
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 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
21 : : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 : : * Boston, MA 02111-1307, USA.
23 : : */
24 : :
25 : : #include "config.h"
26 : :
27 : : #include "girwriter-private.h"
28 : :
29 : : #include "gibaseinfo-private.h"
30 : : #include "girepository.h"
31 : : #include "girepository-private.h"
32 : : #include "gitypelib-internal.h"
33 : :
34 : : #include <errno.h>
35 : : #include <string.h>
36 : : #include <stdio.h>
37 : :
38 : : #include <glib.h>
39 : : #include <glib-object.h>
40 : : #include <glib/gstdio.h>
41 : :
42 : : typedef struct {
43 : : FILE *file;
44 : : GSList *stack;
45 : : gboolean show_all;
46 : : } Xml;
47 : :
48 : : typedef struct {
49 : : char *name;
50 : : unsigned has_children : 1;
51 : : } XmlElement;
52 : :
53 : : static XmlElement *
54 : 0 : xml_element_new (const char *name)
55 : : {
56 : : XmlElement *elem;
57 : :
58 : 0 : elem = g_slice_new (XmlElement);
59 : 0 : elem->name = g_strdup (name);
60 : 0 : elem->has_children = FALSE;
61 : 0 : return elem;
62 : : }
63 : :
64 : : static void
65 : 0 : xml_element_free (XmlElement *elem)
66 : : {
67 : 0 : g_free (elem->name);
68 : 0 : g_slice_free (XmlElement, elem);
69 : 0 : }
70 : :
71 : : static void
72 : : xml_printf (Xml *xml, const char *fmt, ...) G_GNUC_PRINTF (2, 3);
73 : :
74 : : static void
75 : 0 : xml_printf (Xml *xml, const char *fmt, ...)
76 : : {
77 : : va_list ap;
78 : : char *s;
79 : :
80 : 0 : va_start (ap, fmt);
81 : 0 : s = g_markup_vprintf_escaped (fmt, ap);
82 : 0 : fputs (s, xml->file);
83 : 0 : g_free (s);
84 : 0 : va_end (ap);
85 : 0 : }
86 : :
87 : : static void
88 : 0 : xml_start_element (Xml *xml, const char *element_name)
89 : : {
90 : 0 : XmlElement *parent = NULL;
91 : :
92 : 0 : if (xml->stack)
93 : : {
94 : 0 : parent = xml->stack->data;
95 : :
96 : 0 : if (!parent->has_children)
97 : 0 : xml_printf (xml, ">\n");
98 : :
99 : 0 : parent->has_children = TRUE;
100 : : }
101 : :
102 : 0 : xml_printf (xml, "%*s<%s", g_slist_length(xml->stack)*2, "", element_name);
103 : :
104 : 0 : xml->stack = g_slist_prepend (xml->stack, xml_element_new (element_name));
105 : 0 : }
106 : :
107 : : static void
108 : 0 : xml_end_element (Xml *xml, const char *name)
109 : : {
110 : : XmlElement *elem;
111 : :
112 : 0 : g_assert (xml->stack != NULL);
113 : :
114 : 0 : elem = xml->stack->data;
115 : 0 : xml->stack = g_slist_delete_link (xml->stack, xml->stack);
116 : :
117 : 0 : if (name != NULL)
118 : 0 : g_assert_cmpstr (name, ==, elem->name);
119 : :
120 : 0 : if (elem->has_children)
121 : 0 : xml_printf (xml, "%*s</%s>\n", g_slist_length (xml->stack)*2, "", elem->name);
122 : : else
123 : 0 : xml_printf (xml, "/>\n");
124 : :
125 : 0 : xml_element_free (elem);
126 : 0 : }
127 : :
128 : : static void
129 : 0 : xml_end_element_unchecked (Xml *xml)
130 : : {
131 : 0 : xml_end_element (xml, NULL);
132 : 0 : }
133 : :
134 : : static Xml *
135 : 0 : xml_open (FILE *file)
136 : : {
137 : : Xml *xml;
138 : :
139 : 0 : xml = g_slice_new (Xml);
140 : 0 : xml->file = file;
141 : 0 : xml->stack = NULL;
142 : :
143 : 0 : return xml;
144 : : }
145 : :
146 : : static void
147 : 0 : xml_close (Xml *xml)
148 : : {
149 : 0 : g_assert (xml->stack == NULL);
150 : 0 : if (xml->file != NULL)
151 : : {
152 : 0 : fflush (xml->file);
153 : 0 : if (xml->file != stdout)
154 : 0 : fclose (xml->file);
155 : 0 : xml->file = NULL;
156 : : }
157 : 0 : }
158 : :
159 : : static void
160 : 0 : xml_free (Xml *xml)
161 : : {
162 : 0 : xml_close (xml);
163 : 0 : g_slice_free (Xml, xml);
164 : 0 : }
165 : :
166 : :
167 : : static void
168 : 0 : check_unresolved (GIBaseInfo *info)
169 : : {
170 : 0 : if (!GI_IS_UNRESOLVED_INFO (info))
171 : 0 : return;
172 : :
173 : 0 : g_critical ("Found unresolved type '%s' '%s'",
174 : : gi_base_info_get_name (info), gi_base_info_get_namespace (info));
175 : : }
176 : :
177 : : static void
178 : 0 : write_type_name (const char *ns,
179 : : GIBaseInfo *info,
180 : : Xml *file)
181 : : {
182 : 0 : if (strcmp (ns, gi_base_info_get_namespace (info)) != 0)
183 : 0 : xml_printf (file, "%s.", gi_base_info_get_namespace (info));
184 : :
185 : 0 : xml_printf (file, "%s", gi_base_info_get_name (info));
186 : 0 : }
187 : :
188 : : static void
189 : 0 : write_type_name_attribute (const char *ns,
190 : : GIBaseInfo *info,
191 : : const char *attr_name,
192 : : Xml *file)
193 : : {
194 : 0 : xml_printf (file, " %s=\"", attr_name);
195 : 0 : write_type_name (ns, info, file);
196 : 0 : xml_printf (file, "\"");
197 : 0 : }
198 : :
199 : : static void
200 : 0 : write_ownership_transfer (GITransfer transfer,
201 : : Xml *file)
202 : : {
203 : 0 : switch (transfer)
204 : : {
205 : 0 : case GI_TRANSFER_NOTHING:
206 : 0 : xml_printf (file, " transfer-ownership=\"none\"");
207 : 0 : break;
208 : 0 : case GI_TRANSFER_CONTAINER:
209 : 0 : xml_printf (file, " transfer-ownership=\"container\"");
210 : 0 : break;
211 : 0 : case GI_TRANSFER_EVERYTHING:
212 : 0 : xml_printf (file, " transfer-ownership=\"full\"");
213 : 0 : break;
214 : 0 : default:
215 : : g_assert_not_reached ();
216 : : }
217 : 0 : }
218 : :
219 : : static void
220 : 0 : write_type_info (const char *ns,
221 : : GITypeInfo *info,
222 : : Xml *file)
223 : : {
224 : : int tag;
225 : : GITypeInfo *type;
226 : : gboolean is_pointer;
227 : :
228 : 0 : check_unresolved ((GIBaseInfo*)info);
229 : :
230 : 0 : tag = gi_type_info_get_tag (info);
231 : 0 : is_pointer = gi_type_info_is_pointer (info);
232 : :
233 : 0 : if (tag == GI_TYPE_TAG_VOID)
234 : : {
235 : 0 : xml_start_element (file, "type");
236 : :
237 : 0 : xml_printf (file, " name=\"%s\"", is_pointer ? "any" : "none");
238 : :
239 : 0 : xml_end_element (file, "type");
240 : : }
241 : 0 : else if (GI_TYPE_TAG_IS_BASIC (tag))
242 : : {
243 : 0 : xml_start_element (file, "type");
244 : 0 : xml_printf (file, " name=\"%s\"", gi_type_tag_to_string (tag));
245 : 0 : xml_end_element (file, "type");
246 : : }
247 : 0 : else if (tag == GI_TYPE_TAG_ARRAY)
248 : : {
249 : : unsigned int length_index;
250 : : size_t size;
251 : 0 : const char *name = NULL;
252 : :
253 : 0 : xml_start_element (file, "array");
254 : :
255 : 0 : switch (gi_type_info_get_array_type (info)) {
256 : 0 : case GI_ARRAY_TYPE_C:
257 : 0 : break;
258 : 0 : case GI_ARRAY_TYPE_ARRAY:
259 : 0 : name = "GLib.Array";
260 : 0 : break;
261 : 0 : case GI_ARRAY_TYPE_PTR_ARRAY:
262 : 0 : name = "GLib.PtrArray";
263 : 0 : break;
264 : 0 : case GI_ARRAY_TYPE_BYTE_ARRAY:
265 : 0 : name = "GLib.ByteArray";
266 : 0 : break;
267 : 0 : default:
268 : 0 : break;
269 : : }
270 : :
271 : 0 : if (name)
272 : 0 : xml_printf (file, " name=\"%s\"", name);
273 : :
274 : 0 : type = gi_type_info_get_param_type (info, 0);
275 : :
276 : 0 : if (gi_type_info_get_array_length_index (info, &length_index))
277 : 0 : xml_printf (file, " length=\"%u\"", length_index);
278 : :
279 : 0 : if (gi_type_info_get_array_fixed_size (info, &size))
280 : 0 : xml_printf (file, " fixed-size=\"%zu\"", size);
281 : :
282 : 0 : if (gi_type_info_is_zero_terminated (info))
283 : 0 : xml_printf (file, " zero-terminated=\"1\"");
284 : :
285 : 0 : write_type_info (ns, type, file);
286 : :
287 : 0 : gi_base_info_unref ((GIBaseInfo *)type);
288 : :
289 : 0 : xml_end_element (file, "array");
290 : : }
291 : 0 : else if (tag == GI_TYPE_TAG_INTERFACE)
292 : : {
293 : 0 : GIBaseInfo *iface = gi_type_info_get_interface (info);
294 : 0 : xml_start_element (file, "type");
295 : 0 : write_type_name_attribute (ns, iface, "name", file);
296 : 0 : xml_end_element (file, "type");
297 : 0 : gi_base_info_unref (iface);
298 : : }
299 : 0 : else if (tag == GI_TYPE_TAG_GLIST)
300 : : {
301 : 0 : xml_start_element (file, "type");
302 : 0 : xml_printf (file, " name=\"GLib.List\"");
303 : 0 : type = gi_type_info_get_param_type (info, 0);
304 : 0 : if (type)
305 : : {
306 : 0 : write_type_info (ns, type, file);
307 : 0 : gi_base_info_unref ((GIBaseInfo *)type);
308 : : }
309 : 0 : xml_end_element (file, "type");
310 : : }
311 : 0 : else if (tag == GI_TYPE_TAG_GSLIST)
312 : : {
313 : 0 : xml_start_element (file, "type");
314 : 0 : xml_printf (file, " name=\"GLib.SList\"");
315 : 0 : type = gi_type_info_get_param_type (info, 0);
316 : 0 : if (type)
317 : : {
318 : 0 : write_type_info (ns, type, file);
319 : 0 : gi_base_info_unref ((GIBaseInfo *)type);
320 : : }
321 : 0 : xml_end_element (file, "type");
322 : : }
323 : 0 : else if (tag == GI_TYPE_TAG_GHASH)
324 : : {
325 : 0 : xml_start_element (file, "type");
326 : 0 : xml_printf (file, " name=\"GLib.HashTable\"");
327 : 0 : type = gi_type_info_get_param_type (info, 0);
328 : 0 : if (type)
329 : : {
330 : 0 : write_type_info (ns, type, file);
331 : 0 : gi_base_info_unref ((GIBaseInfo *)type);
332 : 0 : type = gi_type_info_get_param_type (info, 1);
333 : 0 : write_type_info (ns, type, file);
334 : 0 : gi_base_info_unref ((GIBaseInfo *)type);
335 : : }
336 : 0 : xml_end_element (file, "type");
337 : : }
338 : 0 : else if (tag == GI_TYPE_TAG_ERROR)
339 : : {
340 : 0 : xml_start_element (file, "type");
341 : 0 : xml_printf (file, " name=\"GLib.Error\"");
342 : 0 : xml_end_element (file, "type");
343 : : }
344 : : else
345 : : {
346 : 0 : g_printerr ("Unhandled type tag %d\n", tag);
347 : : g_assert_not_reached ();
348 : : }
349 : 0 : }
350 : :
351 : : static void
352 : 0 : write_attributes (Xml *file,
353 : : GIBaseInfo *info)
354 : : {
355 : 0 : GIAttributeIter iter = GI_ATTRIBUTE_ITER_INIT;
356 : : const char *name, *value;
357 : :
358 : 0 : while (gi_base_info_iterate_attributes (info, &iter, &name, &value))
359 : : {
360 : 0 : xml_start_element (file, "attribute");
361 : 0 : xml_printf (file, " name=\"%s\" value=\"%s\"", name, value);
362 : 0 : xml_end_element (file, "attribute");
363 : : }
364 : 0 : }
365 : :
366 : : static void
367 : 0 : write_return_value_attributes (Xml *file,
368 : : GICallableInfo *info)
369 : : {
370 : 0 : GIAttributeIter iter = GI_ATTRIBUTE_ITER_INIT;
371 : : const char *name, *value;
372 : :
373 : 0 : while (gi_callable_info_iterate_return_attributes (info, &iter, &name, &value))
374 : : {
375 : 0 : xml_start_element (file, "attribute");
376 : 0 : xml_printf (file, " name=\"%s\" value=\"%s\"", name, value);
377 : 0 : xml_end_element (file, "attribute");
378 : : }
379 : 0 : }
380 : :
381 : : static void
382 : : write_constant_value (const char *ns,
383 : : GITypeInfo *info,
384 : : GIArgument *argument,
385 : : Xml *file);
386 : :
387 : : static void
388 : : write_callback_info (const char *ns,
389 : : GICallbackInfo *info,
390 : : Xml *file);
391 : :
392 : : static void
393 : 0 : write_field_info (const char *ns,
394 : : GIFieldInfo *info,
395 : : GIConstantInfo *branch,
396 : : Xml *file)
397 : : {
398 : : const char *name;
399 : : GIFieldInfoFlags flags;
400 : : size_t size;
401 : : size_t offset;
402 : : GITypeInfo *type;
403 : : GIBaseInfo *interface;
404 : : GIArgument value;
405 : :
406 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
407 : 0 : flags = gi_field_info_get_flags (info);
408 : 0 : size = gi_field_info_get_size (info);
409 : 0 : offset = gi_field_info_get_offset (info);
410 : :
411 : 0 : xml_start_element (file, "field");
412 : 0 : xml_printf (file, " name=\"%s\"", name);
413 : :
414 : : /* Fields are assumed to be read-only
415 : : * (see also girwriter.py and girparser.c)
416 : : */
417 : 0 : if (!(flags & GI_FIELD_IS_READABLE))
418 : 0 : xml_printf (file, " readable=\"0\"");
419 : 0 : if (flags & GI_FIELD_IS_WRITABLE)
420 : 0 : xml_printf (file, " writable=\"1\"");
421 : :
422 : 0 : if (size)
423 : 0 : xml_printf (file, " bits=\"%zu\"", size);
424 : :
425 : 0 : write_attributes (file, (GIBaseInfo*) info);
426 : :
427 : 0 : type = gi_field_info_get_type_info (info);
428 : :
429 : 0 : if (branch)
430 : : {
431 : 0 : xml_printf (file, " branch=\"");
432 : 0 : gi_base_info_unref ((GIBaseInfo *)type);
433 : 0 : type = gi_constant_info_get_type_info (branch);
434 : 0 : gi_constant_info_get_value (branch, &value);
435 : 0 : write_constant_value (ns, type, &value, file);
436 : 0 : xml_printf (file, "\"");
437 : : }
438 : :
439 : 0 : if (file->show_all)
440 : : {
441 : 0 : xml_printf (file, "offset=\"%zu\"", offset);
442 : : }
443 : :
444 : 0 : interface = gi_type_info_get_interface (type);
445 : 0 : if (interface != NULL && GI_IS_CALLBACK_INFO (interface))
446 : 0 : write_callback_info (ns, (GICallbackInfo *)interface, file);
447 : : else
448 : 0 : write_type_info (ns, type, file);
449 : :
450 : 0 : if (interface)
451 : 0 : gi_base_info_unref (interface);
452 : :
453 : 0 : gi_base_info_unref ((GIBaseInfo *)type);
454 : :
455 : 0 : xml_end_element (file, "field");
456 : 0 : }
457 : :
458 : : static void
459 : 0 : write_callable_info (const char *ns,
460 : : GICallableInfo *info,
461 : : Xml *file)
462 : : {
463 : : GITypeInfo *type;
464 : : GICallableInfo *async_func;
465 : : GICallableInfo *sync_func;
466 : : GICallableInfo *finish_func;
467 : :
468 : 0 : if (gi_callable_info_can_throw_gerror (info))
469 : 0 : xml_printf (file, " throws=\"1\"");
470 : :
471 : 0 : write_attributes (file, (GIBaseInfo*) info);
472 : :
473 : 0 : type = gi_callable_info_get_return_type (info);
474 : 0 : async_func = gi_callable_info_get_async_function (info);
475 : 0 : sync_func = gi_callable_info_get_sync_function (info);
476 : 0 : finish_func = gi_callable_info_get_finish_function (info);
477 : :
478 : 0 : if (sync_func)
479 : 0 : xml_printf (file, " glib:sync-func=\"%s\"", gi_base_info_get_name ((GIBaseInfo*) sync_func));
480 : :
481 : 0 : if (finish_func)
482 : 0 : xml_printf (file, " glib:finish-func=\"%s\"", gi_base_info_get_name ((GIBaseInfo*) finish_func));
483 : :
484 : 0 : if (async_func)
485 : 0 : xml_printf (file, " glib:async-func=\"%s\"", gi_base_info_get_name ((GIBaseInfo*) async_func));
486 : :
487 : 0 : xml_start_element (file, "return-value");
488 : :
489 : 0 : write_ownership_transfer (gi_callable_info_get_caller_owns (info), file);
490 : :
491 : 0 : if (gi_callable_info_may_return_null (info))
492 : 0 : xml_printf (file, " allow-none=\"1\"");
493 : :
494 : 0 : if (gi_callable_info_skip_return (info))
495 : 0 : xml_printf (file, " skip=\"1\"");
496 : :
497 : 0 : write_return_value_attributes (file, info);
498 : :
499 : 0 : write_type_info (ns, type, file);
500 : :
501 : 0 : xml_end_element (file, "return-value");
502 : :
503 : 0 : if (gi_callable_info_get_n_args (info) <= 0)
504 : 0 : return;
505 : :
506 : 0 : xml_start_element (file, "parameters");
507 : 0 : for (unsigned int i = 0; i < gi_callable_info_get_n_args (info); i++)
508 : : {
509 : 0 : GIArgInfo *arg = gi_callable_info_get_arg (info, i);
510 : : unsigned int closure_index, destroy_index;
511 : :
512 : 0 : xml_start_element (file, "parameter");
513 : 0 : xml_printf (file, " name=\"%s\"",
514 : : gi_base_info_get_name ((GIBaseInfo *) arg));
515 : :
516 : 0 : write_ownership_transfer (gi_arg_info_get_ownership_transfer (arg), file);
517 : :
518 : 0 : switch (gi_arg_info_get_direction (arg))
519 : : {
520 : 0 : case GI_DIRECTION_IN:
521 : 0 : break;
522 : 0 : case GI_DIRECTION_OUT:
523 : 0 : xml_printf (file, " direction=\"out\" caller-allocates=\"%s\"",
524 : 0 : gi_arg_info_is_caller_allocates (arg) ? "1" : "0");
525 : 0 : break;
526 : 0 : case GI_DIRECTION_INOUT:
527 : 0 : xml_printf (file, " direction=\"inout\"");
528 : 0 : break;
529 : 0 : default:
530 : : g_assert_not_reached ();
531 : : }
532 : :
533 : 0 : if (gi_arg_info_may_be_null (arg))
534 : 0 : xml_printf (file, " allow-none=\"1\"");
535 : :
536 : 0 : if (gi_arg_info_is_return_value (arg))
537 : 0 : xml_printf (file, " retval=\"1\"");
538 : :
539 : 0 : if (gi_arg_info_is_optional (arg))
540 : 0 : xml_printf (file, " optional=\"1\"");
541 : :
542 : 0 : switch (gi_arg_info_get_scope (arg))
543 : : {
544 : 0 : case GI_SCOPE_TYPE_INVALID:
545 : 0 : break;
546 : 0 : case GI_SCOPE_TYPE_CALL:
547 : 0 : xml_printf (file, " scope=\"call\"");
548 : 0 : break;
549 : 0 : case GI_SCOPE_TYPE_ASYNC:
550 : 0 : xml_printf (file, " scope=\"async\"");
551 : 0 : break;
552 : 0 : case GI_SCOPE_TYPE_NOTIFIED:
553 : 0 : xml_printf (file, " scope=\"notified\"");
554 : 0 : break;
555 : 0 : case GI_SCOPE_TYPE_FOREVER:
556 : 0 : xml_printf (file, " scope=\"forever\"");
557 : 0 : break;
558 : 0 : default:
559 : : g_assert_not_reached ();
560 : : }
561 : :
562 : 0 : if (gi_arg_info_get_closure_index (arg, &closure_index))
563 : 0 : xml_printf (file, " closure=\"%u\"", closure_index);
564 : :
565 : 0 : if (gi_arg_info_get_destroy_index (arg, &destroy_index))
566 : 0 : xml_printf (file, " destroy=\"%u\"", destroy_index);
567 : :
568 : 0 : if (gi_arg_info_is_skip (arg))
569 : 0 : xml_printf (file, " skip=\"1\"");
570 : :
571 : 0 : write_attributes (file, (GIBaseInfo*) arg);
572 : :
573 : 0 : type = gi_arg_info_get_type_info (arg);
574 : 0 : write_type_info (ns, type, file);
575 : :
576 : 0 : xml_end_element (file, "parameter");
577 : :
578 : 0 : gi_base_info_unref ((GIBaseInfo *)arg);
579 : : }
580 : :
581 : 0 : xml_end_element (file, "parameters");
582 : 0 : gi_base_info_unref ((GIBaseInfo *)type);
583 : : }
584 : :
585 : : static void
586 : 0 : write_function_info (const char *ns,
587 : : GIFunctionInfo *info,
588 : : Xml *file)
589 : : {
590 : : GIFunctionInfoFlags flags;
591 : : const char *tag;
592 : : const char *name;
593 : : const char *symbol;
594 : : gboolean deprecated;
595 : :
596 : 0 : flags = gi_function_info_get_flags (info);
597 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
598 : 0 : symbol = gi_function_info_get_symbol (info);
599 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
600 : :
601 : 0 : if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
602 : 0 : tag = "constructor";
603 : 0 : else if (flags & GI_FUNCTION_IS_METHOD)
604 : 0 : tag = "method";
605 : : else
606 : 0 : tag = "function";
607 : :
608 : 0 : xml_start_element (file, tag);
609 : 0 : xml_printf (file, " name=\"%s\" c:identifier=\"%s\"",
610 : : name, symbol);
611 : :
612 : 0 : if ((flags & GI_FUNCTION_IS_SETTER) || (flags & GI_FUNCTION_IS_GETTER))
613 : : {
614 : 0 : GIPropertyInfo *property = gi_function_info_get_property (info);
615 : :
616 : 0 : if (property != NULL)
617 : : {
618 : 0 : const char *property_name = gi_base_info_get_name ((GIBaseInfo *)property);
619 : :
620 : 0 : if (flags & GI_FUNCTION_IS_SETTER)
621 : 0 : xml_printf (file, " glib:set-property=\"%s\"", property_name);
622 : 0 : else if (flags & GI_FUNCTION_IS_GETTER)
623 : 0 : xml_printf (file, " glib:get-property=\"%s\"", property_name);
624 : :
625 : 0 : gi_base_info_unref ((GIBaseInfo *) property);
626 : : }
627 : : }
628 : :
629 : 0 : if (deprecated)
630 : 0 : xml_printf (file, " deprecated=\"1\"");
631 : :
632 : 0 : write_callable_info (ns, (GICallableInfo*)info, file);
633 : 0 : xml_end_element (file, tag);
634 : 0 : }
635 : :
636 : : static void
637 : 0 : write_callback_info (const char *ns,
638 : : GICallbackInfo *info,
639 : : Xml *file)
640 : : {
641 : : const char *name;
642 : : gboolean deprecated;
643 : :
644 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
645 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
646 : :
647 : 0 : xml_start_element (file, "callback");
648 : 0 : xml_printf (file, " name=\"%s\"", name);
649 : :
650 : 0 : if (deprecated)
651 : 0 : xml_printf (file, " deprecated=\"1\"");
652 : :
653 : 0 : write_callable_info (ns, (GICallableInfo*)info, file);
654 : 0 : xml_end_element (file, "callback");
655 : 0 : }
656 : :
657 : : static void
658 : 0 : write_struct_info (const char *ns,
659 : : GIStructInfo *info,
660 : : Xml *file)
661 : : {
662 : : const char *name;
663 : : const char *type_name;
664 : : const char *type_init;
665 : : const char *func;
666 : : gboolean deprecated;
667 : : gboolean is_gtype_struct;
668 : : gboolean foreign;
669 : : size_t size;
670 : : unsigned int n_elts;
671 : :
672 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
673 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
674 : :
675 : 0 : type_name = gi_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
676 : 0 : type_init = gi_registered_type_info_get_type_init_function_name ((GIRegisteredTypeInfo*)info);
677 : :
678 : 0 : if (gi_registered_type_info_is_boxed (GI_REGISTERED_TYPE_INFO (info)))
679 : : {
680 : 0 : xml_start_element (file, "glib:boxed");
681 : 0 : xml_printf (file, " glib:name=\"%s\"", name);
682 : : }
683 : : else
684 : : {
685 : 0 : xml_start_element (file, "record");
686 : 0 : xml_printf (file, " name=\"%s\"", name);
687 : : }
688 : :
689 : 0 : if (type_name != NULL)
690 : 0 : xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
691 : :
692 : 0 : if (deprecated)
693 : 0 : xml_printf (file, " deprecated=\"1\"");
694 : :
695 : 0 : is_gtype_struct = gi_struct_info_is_gtype_struct (info);
696 : 0 : if (is_gtype_struct)
697 : 0 : xml_printf (file, " glib:is-gtype-struct=\"1\"");
698 : :
699 : 0 : func = gi_struct_info_get_copy_function_name (info);
700 : 0 : if (func)
701 : 0 : xml_printf (file, " copy-function=\"%s\"", func);
702 : :
703 : 0 : func = gi_struct_info_get_free_function_name (info);
704 : 0 : if (func)
705 : 0 : xml_printf (file, " free-function=\"%s\"", func);
706 : :
707 : 0 : write_attributes (file, (GIBaseInfo*) info);
708 : :
709 : 0 : size = gi_struct_info_get_size (info);
710 : 0 : if (file->show_all)
711 : 0 : xml_printf (file, " size=\"%zu\"", size);
712 : :
713 : 0 : foreign = gi_struct_info_is_foreign (info);
714 : 0 : if (foreign)
715 : 0 : xml_printf (file, " foreign=\"1\"");
716 : :
717 : 0 : n_elts = gi_struct_info_get_n_fields (info) + gi_struct_info_get_n_methods (info);
718 : 0 : if (n_elts > 0)
719 : : {
720 : 0 : for (unsigned int i = 0; i < gi_struct_info_get_n_fields (info); i++)
721 : : {
722 : 0 : GIFieldInfo *field = gi_struct_info_get_field (info, i);
723 : 0 : write_field_info (ns, field, NULL, file);
724 : 0 : gi_base_info_unref ((GIBaseInfo *)field);
725 : : }
726 : :
727 : 0 : for (unsigned int i = 0; i < gi_struct_info_get_n_methods (info); i++)
728 : : {
729 : 0 : GIFunctionInfo *function = gi_struct_info_get_method (info, i);
730 : 0 : write_function_info (ns, function, file);
731 : 0 : gi_base_info_unref ((GIBaseInfo *)function);
732 : : }
733 : :
734 : : }
735 : :
736 : 0 : xml_end_element_unchecked (file);
737 : 0 : }
738 : :
739 : : static void
740 : 0 : write_value_info (const char *ns,
741 : : GIValueInfo *info,
742 : : Xml *file)
743 : : {
744 : : const char *name;
745 : : int64_t value;
746 : : char *value_str;
747 : : gboolean deprecated;
748 : :
749 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
750 : 0 : value = gi_value_info_get_value (info);
751 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
752 : :
753 : 0 : xml_start_element (file, "member");
754 : 0 : value_str = g_strdup_printf ("%" G_GINT64_FORMAT, value);
755 : 0 : xml_printf (file, " name=\"%s\" value=\"%s\"", name, value_str);
756 : 0 : g_free (value_str);
757 : :
758 : 0 : if (deprecated)
759 : 0 : xml_printf (file, " deprecated=\"1\"");
760 : :
761 : 0 : write_attributes (file, (GIBaseInfo*) info);
762 : :
763 : 0 : xml_end_element (file, "member");
764 : 0 : }
765 : :
766 : : static void
767 : 0 : write_constant_value (const char *ns,
768 : : GITypeInfo *type,
769 : : GIArgument *value,
770 : : Xml *file)
771 : : {
772 : 0 : switch (gi_type_info_get_tag (type))
773 : : {
774 : 0 : case GI_TYPE_TAG_BOOLEAN:
775 : 0 : xml_printf (file, "%d", value->v_boolean);
776 : 0 : break;
777 : 0 : case GI_TYPE_TAG_INT8:
778 : 0 : xml_printf (file, "%d", value->v_int8);
779 : 0 : break;
780 : 0 : case GI_TYPE_TAG_UINT8:
781 : 0 : xml_printf (file, "%d", value->v_uint8);
782 : 0 : break;
783 : 0 : case GI_TYPE_TAG_INT16:
784 : 0 : xml_printf (file, "%" G_GINT16_FORMAT, value->v_int16);
785 : 0 : break;
786 : 0 : case GI_TYPE_TAG_UINT16:
787 : 0 : xml_printf (file, "%" G_GUINT16_FORMAT, value->v_uint16);
788 : 0 : break;
789 : 0 : case GI_TYPE_TAG_INT32:
790 : 0 : xml_printf (file, "%" G_GINT32_FORMAT, value->v_int32);
791 : 0 : break;
792 : 0 : case GI_TYPE_TAG_UINT32:
793 : 0 : xml_printf (file, "%" G_GUINT32_FORMAT, value->v_uint32);
794 : 0 : break;
795 : 0 : case GI_TYPE_TAG_INT64:
796 : 0 : xml_printf (file, "%" G_GINT64_FORMAT, value->v_int64);
797 : 0 : break;
798 : 0 : case GI_TYPE_TAG_UINT64:
799 : 0 : xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64);
800 : 0 : break;
801 : 0 : case GI_TYPE_TAG_FLOAT:
802 : 0 : xml_printf (file, "%f", (double)value->v_float);
803 : 0 : break;
804 : 0 : case GI_TYPE_TAG_DOUBLE:
805 : 0 : xml_printf (file, "%f", value->v_double);
806 : 0 : break;
807 : 0 : case GI_TYPE_TAG_UTF8:
808 : : case GI_TYPE_TAG_FILENAME:
809 : 0 : xml_printf (file, "%s", value->v_string);
810 : 0 : break;
811 : 0 : default:
812 : : g_assert_not_reached ();
813 : : }
814 : 0 : }
815 : :
816 : : static void
817 : 0 : write_constant_info (const char *ns,
818 : : GIConstantInfo *info,
819 : : Xml *file)
820 : : {
821 : : GITypeInfo *type;
822 : : const char *name;
823 : : GIArgument value;
824 : :
825 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
826 : :
827 : 0 : xml_start_element (file, "constant");
828 : 0 : xml_printf (file, " name=\"%s\"", name);
829 : :
830 : 0 : type = gi_constant_info_get_type_info (info);
831 : 0 : xml_printf (file, " value=\"");
832 : :
833 : 0 : gi_constant_info_get_value (info, &value);
834 : 0 : write_constant_value (ns, type, &value, file);
835 : 0 : xml_printf (file, "\"");
836 : :
837 : 0 : write_type_info (ns, type, file);
838 : :
839 : 0 : write_attributes (file, (GIBaseInfo*) info);
840 : :
841 : 0 : xml_end_element (file, "constant");
842 : :
843 : 0 : gi_base_info_unref ((GIBaseInfo *)type);
844 : 0 : }
845 : :
846 : :
847 : : static void
848 : 0 : write_enum_info (const char *ns,
849 : : GIEnumInfo *info,
850 : : Xml *file)
851 : : {
852 : : const char *name;
853 : : const char *type_name;
854 : : const char *type_init;
855 : : const char *error_domain;
856 : : gboolean deprecated;
857 : :
858 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
859 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
860 : :
861 : 0 : type_name = gi_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
862 : 0 : type_init = gi_registered_type_info_get_type_init_function_name ((GIRegisteredTypeInfo*)info);
863 : 0 : error_domain = gi_enum_info_get_error_domain (info);
864 : :
865 : 0 : if (GI_IS_ENUM_INFO (info))
866 : 0 : xml_start_element (file, "enumeration");
867 : : else
868 : 0 : xml_start_element (file, "bitfield");
869 : 0 : xml_printf (file, " name=\"%s\"", name);
870 : :
871 : 0 : if (type_init)
872 : 0 : xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
873 : 0 : if (error_domain)
874 : 0 : xml_printf (file, " glib:error-domain=\"%s\"", error_domain);
875 : :
876 : 0 : if (deprecated)
877 : 0 : xml_printf (file, " deprecated=\"1\"");
878 : :
879 : 0 : write_attributes (file, (GIBaseInfo*) info);
880 : :
881 : 0 : for (unsigned int i = 0; i < gi_enum_info_get_n_values (info); i++)
882 : : {
883 : 0 : GIValueInfo *value = gi_enum_info_get_value (info, i);
884 : 0 : write_value_info (ns, value, file);
885 : 0 : gi_base_info_unref ((GIBaseInfo *)value);
886 : : }
887 : :
888 : 0 : xml_end_element_unchecked (file);
889 : 0 : }
890 : :
891 : : static void
892 : 0 : write_signal_info (const char *ns,
893 : : GISignalInfo *info,
894 : : Xml *file)
895 : : {
896 : : GSignalFlags flags;
897 : : const char *name;
898 : : gboolean deprecated;
899 : :
900 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
901 : 0 : flags = gi_signal_info_get_flags (info);
902 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
903 : :
904 : 0 : xml_start_element (file, "glib:signal");
905 : 0 : xml_printf (file, " name=\"%s\"", name);
906 : :
907 : 0 : if (deprecated)
908 : 0 : xml_printf (file, " deprecated=\"1\"");
909 : :
910 : 0 : if (flags & G_SIGNAL_RUN_FIRST)
911 : 0 : xml_printf (file, " when=\"FIRST\"");
912 : 0 : else if (flags & G_SIGNAL_RUN_LAST)
913 : 0 : xml_printf (file, " when=\"LAST\"");
914 : 0 : else if (flags & G_SIGNAL_RUN_CLEANUP)
915 : 0 : xml_printf (file, " when=\"CLEANUP\"");
916 : :
917 : 0 : if (flags & G_SIGNAL_NO_RECURSE)
918 : 0 : xml_printf (file, " no-recurse=\"1\"");
919 : :
920 : 0 : if (flags & G_SIGNAL_DETAILED)
921 : 0 : xml_printf (file, " detailed=\"1\"");
922 : :
923 : 0 : if (flags & G_SIGNAL_ACTION)
924 : 0 : xml_printf (file, " action=\"1\"");
925 : :
926 : 0 : if (flags & G_SIGNAL_NO_HOOKS)
927 : 0 : xml_printf (file, " no-hooks=\"1\"");
928 : :
929 : 0 : write_callable_info (ns, (GICallableInfo*)info, file);
930 : :
931 : 0 : xml_end_element (file, "glib:signal");
932 : 0 : }
933 : :
934 : : static void
935 : 0 : write_vfunc_info (const char *ns,
936 : : GIVFuncInfo *info,
937 : : Xml *file)
938 : : {
939 : : GIVFuncInfoFlags flags;
940 : : const char *name;
941 : : GIFunctionInfo *invoker;
942 : : gboolean deprecated;
943 : : size_t offset;
944 : :
945 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
946 : 0 : flags = gi_vfunc_info_get_flags (info);
947 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
948 : 0 : offset = gi_vfunc_info_get_offset (info);
949 : 0 : invoker = gi_vfunc_info_get_invoker (info);
950 : :
951 : 0 : xml_start_element (file, "virtual-method");
952 : 0 : xml_printf (file, " name=\"%s\"", name);
953 : :
954 : 0 : if (deprecated)
955 : 0 : xml_printf (file, " deprecated=\"1\"");
956 : :
957 : 0 : if (flags & GI_VFUNC_MUST_CHAIN_UP)
958 : 0 : xml_printf (file, " must-chain-up=\"1\"");
959 : :
960 : 0 : if (flags & GI_VFUNC_MUST_OVERRIDE)
961 : 0 : xml_printf (file, " override=\"always\"");
962 : 0 : else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE)
963 : 0 : xml_printf (file, " override=\"never\"");
964 : :
965 : 0 : xml_printf (file, " offset=\"%zu\"", offset);
966 : :
967 : 0 : if (invoker)
968 : : {
969 : 0 : xml_printf (file, " invoker=\"%s\"", gi_base_info_get_name ((GIBaseInfo*)invoker));
970 : 0 : gi_base_info_unref ((GIBaseInfo *)invoker);
971 : : }
972 : :
973 : 0 : write_callable_info (ns, (GICallableInfo*)info, file);
974 : :
975 : 0 : xml_end_element (file, "virtual-method");
976 : 0 : }
977 : :
978 : : static void
979 : 0 : write_property_info (const char *ns,
980 : : GIPropertyInfo *info,
981 : : Xml *file)
982 : : {
983 : : GParamFlags flags;
984 : : const char *name;
985 : : gboolean deprecated;
986 : : GITypeInfo *type;
987 : :
988 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
989 : 0 : flags = gi_property_info_get_flags (info);
990 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
991 : :
992 : 0 : xml_start_element (file, "property");
993 : 0 : xml_printf (file, " name=\"%s\"", name);
994 : :
995 : 0 : if (deprecated)
996 : 0 : xml_printf (file, " deprecated=\"1\"");
997 : :
998 : : /* Properties are assumed to be read-only (see also girwriter.py) */
999 : 0 : if (!(flags & G_PARAM_READABLE))
1000 : 0 : xml_printf (file, " readable=\"0\"");
1001 : 0 : if (flags & G_PARAM_WRITABLE)
1002 : 0 : xml_printf (file, " writable=\"1\"");
1003 : :
1004 : 0 : if (flags & G_PARAM_CONSTRUCT)
1005 : 0 : xml_printf (file, " construct=\"1\"");
1006 : :
1007 : 0 : if (flags & G_PARAM_CONSTRUCT_ONLY)
1008 : 0 : xml_printf (file, " construct-only=\"1\"");
1009 : :
1010 : 0 : if (flags & G_PARAM_READABLE)
1011 : : {
1012 : 0 : GIFunctionInfo *getter = gi_property_info_get_getter (info);
1013 : :
1014 : 0 : if (getter != NULL)
1015 : : {
1016 : 0 : xml_printf (file, " getter=\"%s\"", gi_base_info_get_name ((GIBaseInfo *) getter));
1017 : 0 : gi_base_info_unref ((GIBaseInfo *) getter);
1018 : : }
1019 : : }
1020 : :
1021 : 0 : if (flags & G_PARAM_WRITABLE)
1022 : : {
1023 : 0 : GIFunctionInfo *setter = gi_property_info_get_setter (info);
1024 : :
1025 : 0 : if (setter != NULL)
1026 : : {
1027 : 0 : xml_printf (file, " setter=\"%s\"", gi_base_info_get_name ((GIBaseInfo *) setter));
1028 : 0 : gi_base_info_unref ((GIBaseInfo *) setter);
1029 : : }
1030 : : }
1031 : :
1032 : 0 : write_ownership_transfer (gi_property_info_get_ownership_transfer (info), file);
1033 : :
1034 : 0 : write_attributes (file, (GIBaseInfo*) info);
1035 : :
1036 : 0 : type = gi_property_info_get_type_info (info);
1037 : :
1038 : 0 : write_type_info (ns, type, file);
1039 : :
1040 : 0 : xml_end_element (file, "property");
1041 : 0 : }
1042 : :
1043 : : static void
1044 : 0 : write_object_info (const char *ns,
1045 : : GIObjectInfo *info,
1046 : : Xml *file)
1047 : : {
1048 : : const char *name;
1049 : : const char *type_name;
1050 : : const char *type_init;
1051 : : const char *func;
1052 : : gboolean deprecated;
1053 : : gboolean is_abstract;
1054 : : gboolean is_fundamental;
1055 : : gboolean is_final;
1056 : : GIObjectInfo *pnode;
1057 : : GIStructInfo *class_struct;
1058 : :
1059 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
1060 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
1061 : 0 : is_abstract = gi_object_info_get_abstract (info);
1062 : 0 : is_fundamental = gi_object_info_get_fundamental (info);
1063 : 0 : is_final = gi_object_info_get_final (info);
1064 : :
1065 : 0 : type_name = gi_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
1066 : 0 : type_init = gi_registered_type_info_get_type_init_function_name ((GIRegisteredTypeInfo*)info);
1067 : 0 : xml_start_element (file, "class");
1068 : 0 : xml_printf (file, " name=\"%s\"", name);
1069 : :
1070 : 0 : pnode = gi_object_info_get_parent (info);
1071 : 0 : if (pnode)
1072 : : {
1073 : 0 : write_type_name_attribute (ns, (GIBaseInfo *)pnode, "parent", file);
1074 : 0 : gi_base_info_unref ((GIBaseInfo *)pnode);
1075 : : }
1076 : :
1077 : 0 : class_struct = gi_object_info_get_class_struct (info);
1078 : 0 : if (class_struct)
1079 : : {
1080 : 0 : write_type_name_attribute (ns, (GIBaseInfo*) class_struct, "glib:type-struct", file);
1081 : 0 : gi_base_info_unref ((GIBaseInfo*)class_struct);
1082 : : }
1083 : :
1084 : 0 : if (is_abstract)
1085 : 0 : xml_printf (file, " abstract=\"1\"");
1086 : :
1087 : 0 : if (is_final)
1088 : 0 : xml_printf (file, " final=\"1\"");
1089 : :
1090 : 0 : xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
1091 : :
1092 : 0 : if (is_fundamental)
1093 : 0 : xml_printf (file, " glib:fundamental=\"1\"");
1094 : :
1095 : 0 : func = gi_object_info_get_unref_function_name (info);
1096 : 0 : if (func)
1097 : 0 : xml_printf (file, " glib:unref-function=\"%s\"", func);
1098 : :
1099 : 0 : func = gi_object_info_get_ref_function_name (info);
1100 : 0 : if (func)
1101 : 0 : xml_printf (file, " glib:ref-function=\"%s\"", func);
1102 : :
1103 : 0 : func = gi_object_info_get_set_value_function_name (info);
1104 : 0 : if (func)
1105 : 0 : xml_printf (file, " glib:set-value-function=\"%s\"", func);
1106 : :
1107 : 0 : func = gi_object_info_get_get_value_function_name (info);
1108 : 0 : if (func)
1109 : 0 : xml_printf (file, " glib:get-value-function=\"%s\"", func);
1110 : :
1111 : 0 : if (deprecated)
1112 : 0 : xml_printf (file, " deprecated=\"1\"");
1113 : :
1114 : 0 : write_attributes (file, (GIBaseInfo*) info);
1115 : :
1116 : 0 : if (gi_object_info_get_n_interfaces (info) > 0)
1117 : : {
1118 : 0 : for (unsigned int i = 0; i < gi_object_info_get_n_interfaces (info); i++)
1119 : : {
1120 : 0 : GIInterfaceInfo *imp = gi_object_info_get_interface (info, i);
1121 : 0 : xml_start_element (file, "implements");
1122 : 0 : write_type_name_attribute (ns, (GIBaseInfo *)imp, "name", file);
1123 : 0 : xml_end_element (file, "implements");
1124 : 0 : gi_base_info_unref ((GIBaseInfo*)imp);
1125 : : }
1126 : : }
1127 : :
1128 : 0 : for (unsigned int i = 0; i < gi_object_info_get_n_fields (info); i++)
1129 : : {
1130 : 0 : GIFieldInfo *field = gi_object_info_get_field (info, i);
1131 : 0 : write_field_info (ns, field, NULL, file);
1132 : 0 : gi_base_info_unref ((GIBaseInfo *)field);
1133 : : }
1134 : :
1135 : 0 : for (unsigned int i = 0; i < gi_object_info_get_n_methods (info); i++)
1136 : : {
1137 : 0 : GIFunctionInfo *function = gi_object_info_get_method (info, i);
1138 : 0 : write_function_info (ns, function, file);
1139 : 0 : gi_base_info_unref ((GIBaseInfo *)function);
1140 : : }
1141 : :
1142 : 0 : for (unsigned int i = 0; i < gi_object_info_get_n_properties (info); i++)
1143 : : {
1144 : 0 : GIPropertyInfo *prop = gi_object_info_get_property (info, i);
1145 : 0 : write_property_info (ns, prop, file);
1146 : 0 : gi_base_info_unref ((GIBaseInfo *)prop);
1147 : : }
1148 : :
1149 : 0 : for (unsigned int i = 0; i < gi_object_info_get_n_signals (info); i++)
1150 : : {
1151 : 0 : GISignalInfo *signal = gi_object_info_get_signal (info, i);
1152 : 0 : write_signal_info (ns, signal, file);
1153 : 0 : gi_base_info_unref ((GIBaseInfo *)signal);
1154 : : }
1155 : :
1156 : 0 : for (unsigned int i = 0; i < gi_object_info_get_n_vfuncs (info); i++)
1157 : : {
1158 : 0 : GIVFuncInfo *vfunc = gi_object_info_get_vfunc (info, i);
1159 : 0 : write_vfunc_info (ns, vfunc, file);
1160 : 0 : gi_base_info_unref ((GIBaseInfo *)vfunc);
1161 : : }
1162 : :
1163 : 0 : for (unsigned int i = 0; i < gi_object_info_get_n_constants (info); i++)
1164 : : {
1165 : 0 : GIConstantInfo *constant = gi_object_info_get_constant (info, i);
1166 : 0 : write_constant_info (ns, constant, file);
1167 : 0 : gi_base_info_unref ((GIBaseInfo *)constant);
1168 : : }
1169 : :
1170 : 0 : xml_end_element (file, "class");
1171 : 0 : }
1172 : :
1173 : : static void
1174 : 0 : write_interface_info (const char *ns,
1175 : : GIInterfaceInfo *info,
1176 : : Xml *file)
1177 : : {
1178 : : const char *name;
1179 : : const char *type_name;
1180 : : const char *type_init;
1181 : : GIStructInfo *class_struct;
1182 : : gboolean deprecated;
1183 : :
1184 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
1185 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
1186 : :
1187 : 0 : type_name = gi_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
1188 : 0 : type_init = gi_registered_type_info_get_type_init_function_name ((GIRegisteredTypeInfo*)info);
1189 : 0 : xml_start_element (file, "interface");
1190 : 0 : xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"",
1191 : : name, type_name, type_init);
1192 : :
1193 : 0 : class_struct = gi_interface_info_get_iface_struct (info);
1194 : 0 : if (class_struct)
1195 : : {
1196 : 0 : write_type_name_attribute (ns, (GIBaseInfo*) class_struct, "glib:type-struct", file);
1197 : 0 : gi_base_info_unref ((GIBaseInfo*)class_struct);
1198 : : }
1199 : :
1200 : 0 : if (deprecated)
1201 : 0 : xml_printf (file, " deprecated=\"1\"");
1202 : :
1203 : 0 : write_attributes (file, (GIBaseInfo*) info);
1204 : :
1205 : 0 : if (gi_interface_info_get_n_prerequisites (info) > 0)
1206 : : {
1207 : 0 : for (unsigned int i = 0; i < gi_interface_info_get_n_prerequisites (info); i++)
1208 : : {
1209 : 0 : GIBaseInfo *req = gi_interface_info_get_prerequisite (info, i);
1210 : :
1211 : 0 : xml_start_element (file, "prerequisite");
1212 : 0 : write_type_name_attribute (ns, req, "name", file);
1213 : :
1214 : 0 : xml_end_element_unchecked (file);
1215 : 0 : gi_base_info_unref (req);
1216 : : }
1217 : : }
1218 : :
1219 : 0 : for (unsigned int i = 0; i < gi_interface_info_get_n_methods (info); i++)
1220 : : {
1221 : 0 : GIFunctionInfo *function = gi_interface_info_get_method (info, i);
1222 : 0 : write_function_info (ns, function, file);
1223 : 0 : gi_base_info_unref ((GIBaseInfo *)function);
1224 : : }
1225 : :
1226 : 0 : for (unsigned int i = 0; i < gi_interface_info_get_n_properties (info); i++)
1227 : : {
1228 : 0 : GIPropertyInfo *prop = gi_interface_info_get_property (info, i);
1229 : 0 : write_property_info (ns, prop, file);
1230 : 0 : gi_base_info_unref ((GIBaseInfo *)prop);
1231 : : }
1232 : :
1233 : 0 : for (unsigned int i = 0; i < gi_interface_info_get_n_signals (info); i++)
1234 : : {
1235 : 0 : GISignalInfo *signal = gi_interface_info_get_signal (info, i);
1236 : 0 : write_signal_info (ns, signal, file);
1237 : 0 : gi_base_info_unref ((GIBaseInfo *)signal);
1238 : : }
1239 : :
1240 : 0 : for (unsigned int i = 0; i < gi_interface_info_get_n_vfuncs (info); i++)
1241 : : {
1242 : 0 : GIVFuncInfo *vfunc = gi_interface_info_get_vfunc (info, i);
1243 : 0 : write_vfunc_info (ns, vfunc, file);
1244 : 0 : gi_base_info_unref ((GIBaseInfo *)vfunc);
1245 : : }
1246 : :
1247 : 0 : for (unsigned int i = 0; i < gi_interface_info_get_n_constants (info); i++)
1248 : : {
1249 : 0 : GIConstantInfo *constant = gi_interface_info_get_constant (info, i);
1250 : 0 : write_constant_info (ns, constant, file);
1251 : 0 : gi_base_info_unref ((GIBaseInfo *)constant);
1252 : : }
1253 : :
1254 : 0 : xml_end_element (file, "interface");
1255 : 0 : }
1256 : :
1257 : : static void
1258 : 0 : write_union_info (const char *ns,
1259 : : GIUnionInfo *info,
1260 : : Xml *file)
1261 : : {
1262 : : const char *name;
1263 : : const char *type_name;
1264 : : const char *type_init;
1265 : : const char *func;
1266 : : gboolean deprecated;
1267 : : size_t size;
1268 : :
1269 : 0 : name = gi_base_info_get_name ((GIBaseInfo *)info);
1270 : 0 : deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
1271 : :
1272 : 0 : type_name = gi_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
1273 : 0 : type_init = gi_registered_type_info_get_type_init_function_name ((GIRegisteredTypeInfo*)info);
1274 : :
1275 : : /* FIXME: Add support for boxed unions */
1276 : 0 : xml_start_element (file, "union");
1277 : 0 : xml_printf (file, " name=\"%s\"", name);
1278 : :
1279 : 0 : if (type_name)
1280 : 0 : xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
1281 : :
1282 : 0 : if (deprecated)
1283 : 0 : xml_printf (file, " deprecated=\"1\"");
1284 : :
1285 : 0 : size = gi_union_info_get_size (info);
1286 : 0 : if (file->show_all)
1287 : 0 : xml_printf (file, " size=\"%" G_GSIZE_FORMAT "\"", size);
1288 : :
1289 : 0 : func = gi_union_info_get_copy_function_name (info);
1290 : 0 : if (func)
1291 : 0 : xml_printf (file, " copy-function=\"%s\"", func);
1292 : :
1293 : 0 : func = gi_union_info_get_free_function_name (info);
1294 : 0 : if (func)
1295 : 0 : xml_printf (file, " free-function=\"%s\"", func);
1296 : :
1297 : 0 : write_attributes (file, (GIBaseInfo*) info);
1298 : :
1299 : 0 : if (gi_union_info_is_discriminated (info))
1300 : : {
1301 : : size_t offset;
1302 : : GITypeInfo *type;
1303 : :
1304 : 0 : gi_union_info_get_discriminator_offset (info, &offset);
1305 : 0 : type = gi_union_info_get_discriminator_type (info);
1306 : :
1307 : 0 : xml_start_element (file, "discriminator");
1308 : 0 : xml_printf (file, " offset=\"%zu\" type=\"", offset);
1309 : 0 : write_type_info (ns, type, file);
1310 : 0 : xml_end_element (file, "discriminator");
1311 : 0 : gi_base_info_unref ((GIBaseInfo *)type);
1312 : : }
1313 : :
1314 : 0 : for (unsigned int i = 0; i < gi_union_info_get_n_fields (info); i++)
1315 : : {
1316 : 0 : GIFieldInfo *field = gi_union_info_get_field (info, i);
1317 : 0 : GIConstantInfo *constant = gi_union_info_get_discriminator (info, i);
1318 : 0 : write_field_info (ns, field, constant, file);
1319 : 0 : gi_base_info_unref ((GIBaseInfo *)field);
1320 : 0 : if (constant)
1321 : 0 : gi_base_info_unref ((GIBaseInfo *)constant);
1322 : : }
1323 : :
1324 : 0 : for (unsigned int i = 0; i < gi_union_info_get_n_methods (info); i++)
1325 : : {
1326 : 0 : GIFunctionInfo *function = gi_union_info_get_method (info, i);
1327 : 0 : write_function_info (ns, function, file);
1328 : 0 : gi_base_info_unref ((GIBaseInfo *)function);
1329 : : }
1330 : :
1331 : 0 : xml_end_element (file, "union");
1332 : 0 : }
1333 : :
1334 : :
1335 : : /**
1336 : : * gi_ir_writer_write:
1337 : : * @repository: repository containing @ns
1338 : : * @filename: (type filename): filename to write to
1339 : : * @ns: GIR namespace to write
1340 : : * @needs_prefix: if the filename needs prefixing
1341 : : * @show_all: if field size calculations should be included
1342 : : *
1343 : : * Writes the output of a typelib represented by @ns
1344 : : * into a GIR xml file named @filename.
1345 : : *
1346 : : * Since: 2.80
1347 : : */
1348 : : void
1349 : 0 : gi_ir_writer_write (GIRepository *repository,
1350 : : const char *filename,
1351 : : const char *ns,
1352 : : gboolean needs_prefix,
1353 : : gboolean show_all)
1354 : : {
1355 : : FILE *ofile;
1356 : : size_t i;
1357 : : unsigned int j;
1358 : : char **dependencies;
1359 : : Xml *xml;
1360 : :
1361 : 0 : if (filename == NULL)
1362 : 0 : ofile = stdout;
1363 : : else
1364 : : {
1365 : : char *full_filename;
1366 : :
1367 : 0 : if (needs_prefix)
1368 : 0 : full_filename = g_strdup_printf ("%s-%s", ns, filename);
1369 : : else
1370 : 0 : full_filename = g_strdup (filename);
1371 : 0 : ofile = g_fopen (filename, "w");
1372 : :
1373 : 0 : if (ofile == NULL)
1374 : : {
1375 : 0 : g_fprintf (stderr, "failed to open '%s': %s\n",
1376 : 0 : full_filename, g_strerror (errno));
1377 : 0 : g_free (full_filename);
1378 : :
1379 : 0 : return;
1380 : : }
1381 : :
1382 : 0 : g_free (full_filename);
1383 : : }
1384 : :
1385 : 0 : xml = xml_open (ofile);
1386 : 0 : xml->show_all = show_all;
1387 : 0 : xml_printf (xml, "<?xml version=\"1.0\"?>\n");
1388 : 0 : xml_start_element (xml, "repository");
1389 : 0 : xml_printf (xml, " version=\"1.0\"\n"
1390 : : " xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n"
1391 : : " xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n"
1392 : : " xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
1393 : :
1394 : 0 : dependencies = gi_repository_get_immediate_dependencies (repository, ns, NULL);
1395 : 0 : if (dependencies != NULL)
1396 : : {
1397 : 0 : for (i = 0; dependencies[i]; i++)
1398 : : {
1399 : 0 : char **parts = g_strsplit (dependencies[i], "-", 2);
1400 : 0 : xml_start_element (xml, "include");
1401 : 0 : xml_printf (xml, " name=\"%s\" version=\"%s\"", parts[0], parts[1]);
1402 : 0 : xml_end_element (xml, "include");
1403 : 0 : g_strfreev (parts);
1404 : : }
1405 : : }
1406 : :
1407 : : if (TRUE)
1408 : : {
1409 : : const char * const *shared_libraries;
1410 : : const char *c_prefix;
1411 : 0 : const char *cur_ns = ns;
1412 : : const char *cur_version;
1413 : : unsigned int n_infos;
1414 : :
1415 : 0 : cur_version = gi_repository_get_version (repository, cur_ns);
1416 : :
1417 : 0 : shared_libraries = gi_repository_get_shared_libraries (repository, cur_ns, NULL);
1418 : 0 : c_prefix = gi_repository_get_c_prefix (repository, cur_ns);
1419 : 0 : xml_start_element (xml, "namespace");
1420 : 0 : xml_printf (xml, " name=\"%s\" version=\"%s\"", cur_ns, cur_version);
1421 : 0 : if (shared_libraries != NULL)
1422 : : {
1423 : 0 : char *shared_libraries_str = g_strjoinv (",", (char **) shared_libraries);
1424 : 0 : xml_printf (xml, " shared-library=\"%s\"", shared_libraries_str);
1425 : 0 : g_free (shared_libraries_str);
1426 : : }
1427 : 0 : if (c_prefix)
1428 : 0 : xml_printf (xml, " c:prefix=\"%s\"", c_prefix);
1429 : :
1430 : 0 : n_infos = gi_repository_get_n_infos (repository, cur_ns);
1431 : 0 : for (j = 0; j < n_infos; j++)
1432 : : {
1433 : 0 : GIBaseInfo *info = gi_repository_get_info (repository, cur_ns, j);
1434 : :
1435 : 0 : if (GI_IS_FUNCTION_INFO (info))
1436 : 0 : write_function_info (ns, (GIFunctionInfo *)info, xml);
1437 : 0 : else if (GI_IS_CALLBACK_INFO (info))
1438 : 0 : write_callback_info (ns, (GICallbackInfo *)info, xml);
1439 : 0 : else if (GI_IS_STRUCT_INFO (info))
1440 : 0 : write_struct_info (ns, (GIStructInfo *)info, xml);
1441 : 0 : else if (GI_IS_UNION_INFO (info))
1442 : 0 : write_union_info (ns, (GIUnionInfo *)info, xml);
1443 : 0 : else if (GI_IS_ENUM_INFO (info) ||
1444 : 0 : GI_IS_FLAGS_INFO (info))
1445 : 0 : write_enum_info (ns, (GIEnumInfo *)info, xml);
1446 : 0 : else if (GI_IS_CONSTANT_INFO (info))
1447 : 0 : write_constant_info (ns, (GIConstantInfo *)info, xml);
1448 : 0 : else if (GI_IS_OBJECT_INFO (info))
1449 : 0 : write_object_info (ns, (GIObjectInfo *)info, xml);
1450 : 0 : else if (GI_IS_INTERFACE_INFO (info))
1451 : 0 : write_interface_info (ns, (GIInterfaceInfo *)info, xml);
1452 : : else
1453 : 0 : g_error ("unknown info type %s", g_type_name (G_TYPE_FROM_INSTANCE (info)));
1454 : :
1455 : 0 : gi_base_info_unref (info);
1456 : : }
1457 : :
1458 : 0 : xml_end_element (xml, "namespace");
1459 : : }
1460 : :
1461 : 0 : xml_end_element (xml, "repository");
1462 : :
1463 : 0 : xml_free (xml);
1464 : : }
|