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