1 /* -*- Mode: C; c-file-style: "gnu"; -*- */
2 /* GObject introspection: IDL generator
4 * Copyright (C) 2005 Matthias Clasen
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
26 #include <glib-object.h>
27 #include <glib/gstdio.h>
29 #include "girepository.h"
32 /* FIXME: Avoid global */
33 static gchar *output = NULL;
34 gchar **includedirs = NULL;
43 guint has_children : 1;
47 xml_element_new (const char *name)
51 elem = g_new (XmlElement, 1);
52 elem->name = g_strdup (name);
53 elem->has_children = FALSE;
58 xml_element_free (XmlElement *elem)
65 xml_printf (Xml *xml, const char *fmt, ...)
71 s = g_markup_vprintf_escaped (fmt, ap);
78 xml_start_element (Xml *xml, const char *element_name)
80 XmlElement *parent = NULL;
84 parent = xml->stack->data;
86 if (!parent->has_children)
87 xml_printf (xml, ">\n");
89 parent->has_children = TRUE;
92 xml_printf (xml, "%*s<%s", g_slist_length(xml->stack)*2, "", element_name);
94 xml->stack = g_slist_prepend (xml->stack, xml_element_new (element_name));
98 xml_end_element (Xml *xml, const char *name)
102 g_assert (xml->stack != NULL);
104 elem = xml->stack->data;
105 xml->stack = g_slist_delete_link (xml->stack, xml->stack);
108 g_assert_cmpstr (name, ==, elem->name);
110 if (elem->has_children)
111 xml_printf (xml, "%*s</%s>\n", g_slist_length (xml->stack)*2, "", elem->name);
113 xml_printf (xml, "/>\n");
115 xml_element_free (elem);
119 xml_end_element_unchecked (Xml *xml)
121 xml_end_element (xml, NULL);
125 xml_open (FILE *file)
129 xml = g_new (Xml, 1);
139 g_assert (xml->stack == NULL);
140 if (xml->file != NULL)
143 if (xml->file != stdout)
158 check_unresolved (GIBaseInfo *info)
160 if (g_base_info_get_type (info) != GI_INFO_TYPE_UNRESOLVED)
163 g_critical ("Found unresolved type '%s' '%s'\n",
164 g_base_info_get_name (info), g_base_info_get_namespace (info));
168 write_type_name (const gchar *namespace,
172 if (strcmp (namespace, g_base_info_get_namespace (info)) != 0)
173 xml_printf (file, "%s.", g_base_info_get_namespace (info));
175 xml_printf (file, "%s", g_base_info_get_name (info));
179 write_type_name_attribute (const gchar *namespace,
181 const char *attr_name,
184 xml_printf (file, " %s=\"", attr_name);
185 write_type_name (namespace, info, file);
186 xml_printf (file, "\"");
190 write_type_info (const gchar *namespace,
199 check_unresolved ((GIBaseInfo*)info);
201 tag = g_type_info_get_tag (info);
202 is_pointer = g_type_info_is_pointer (info);
204 if (tag == GI_TYPE_TAG_VOID)
206 xml_start_element (file, "type");
208 xml_printf (file, " name=\"%s\"", is_pointer ? "any" : "none");
210 xml_end_element (file, "type");
212 else if (G_TYPE_TAG_IS_BASIC (tag))
214 xml_start_element (file, "type");
215 xml_printf (file, " name=\"%s\"", g_type_tag_to_string (tag));
216 xml_end_element (file, "type");
218 else if (tag == GI_TYPE_TAG_ARRAY)
222 xml_start_element (file, "array");
224 type = g_type_info_get_param_type (info, 0);
226 length = g_type_info_get_array_length (info);
229 xml_printf (file, " length=\"%d\"", length);
231 if (g_type_info_is_zero_terminated (info))
232 xml_printf (file, " zero-terminated=\"1\"");
234 write_type_info (namespace, type, file);
236 g_base_info_unref ((GIBaseInfo *)type);
238 xml_end_element (file, "array");
240 else if (tag == GI_TYPE_TAG_INTERFACE)
242 GIBaseInfo *iface = g_type_info_get_interface (info);
243 xml_start_element (file, "type");
244 write_type_name_attribute (namespace, iface, "name", file);
245 xml_end_element (file, "type");
246 g_base_info_unref (iface);
248 else if (tag == GI_TYPE_TAG_GLIST)
250 xml_start_element (file, "type");
251 xml_printf (file, " name=\"GLib.List\"");
252 type = g_type_info_get_param_type (info, 0);
255 write_type_info (namespace, type, file);
256 g_base_info_unref ((GIBaseInfo *)type);
258 xml_end_element (file, "type");
260 else if (tag == GI_TYPE_TAG_GSLIST)
262 xml_start_element (file, "type");
263 xml_printf (file, " name=\"GLib.SList\"");
264 type = g_type_info_get_param_type (info, 0);
267 write_type_info (namespace, type, file);
268 g_base_info_unref ((GIBaseInfo *)type);
270 xml_end_element (file, "type");
272 else if (tag == GI_TYPE_TAG_GHASH)
274 xml_start_element (file, "type");
275 xml_printf (file, " name=\"GLib.HashTable\"");
276 type = g_type_info_get_param_type (info, 0);
279 write_type_info (namespace, type, file);
280 g_base_info_unref ((GIBaseInfo *)type);
281 type = g_type_info_get_param_type (info, 1);
282 write_type_info (namespace, type, file);
283 g_base_info_unref ((GIBaseInfo *)type);
285 xml_end_element (file, "type");
287 else if (tag == GI_TYPE_TAG_ERROR)
291 xml_start_element (file, "type");
292 xml_printf (file, " name=\"GLib.Error\"");
294 n = g_type_info_get_n_error_domains (info);
297 for (i = 0; i < n; i++)
299 GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i);
300 xml_start_element (file, "type");
301 write_type_name_attribute (namespace, (GIBaseInfo *)ed, "name", file);
302 xml_end_element (file, "type");
303 g_base_info_unref ((GIBaseInfo *)ed);
307 xml_end_element (file, "type");
311 g_printerr ("Unhandled type tag %d\n", tag);
312 g_assert_not_reached ();
317 write_constant_value (const gchar *namespace,
323 write_field_info (const gchar *namespace,
325 GIConstantInfo *branch,
329 GIFieldInfoFlags flags;
335 name = g_base_info_get_name ((GIBaseInfo *)info);
336 flags = g_field_info_get_flags (info);
337 size = g_field_info_get_size (info);
338 offset = g_field_info_get_offset (info);
340 xml_start_element (file, "field");
341 xml_printf (file, " name=\"%s\"", name);
343 /* Fields are assumed to be read-only
344 * (see also girwriter.py and girparser.c)
346 if (!(flags & GI_FIELD_IS_READABLE))
347 xml_printf (file, " readable=\"0\"");
348 if (flags & GI_FIELD_IS_WRITABLE)
349 xml_printf (file, " writable=\"1\"");
352 xml_printf (file, " bits=\"%d\"", size);
354 xml_printf (file, " offset=\"%d\"", offset);
356 type = g_field_info_get_type (info);
360 xml_printf (file, " branch=\"");
361 type = g_constant_info_get_type (branch);
362 g_constant_info_get_value (branch, &value);
363 write_constant_value (namespace, type, &value, file);
364 xml_printf (file, "\"");
367 write_type_info (namespace, type, file);
368 g_base_info_unref ((GIBaseInfo *)type);
370 xml_end_element (file, "field");
374 write_callable_info (const gchar *namespace,
375 GICallableInfo *info,
381 type = g_callable_info_get_return_type (info);
383 xml_start_element (file, "return-value");
385 if (g_type_info_is_pointer (type))
387 switch (g_callable_info_get_caller_owns (info))
389 case GI_TRANSFER_NOTHING:
391 case GI_TRANSFER_CONTAINER:
392 xml_printf (file, " transfer-ownership=\"container\"");
394 case GI_TRANSFER_EVERYTHING:
395 xml_printf (file, " transfer-ownership=\"full\"");
398 g_assert_not_reached ();
402 if (g_callable_info_may_return_null (info))
403 xml_printf (file, " null-ok=\"1\"");
405 write_type_info (namespace, type, file);
407 xml_end_element (file, "return-value");
409 if (g_callable_info_get_n_args (info) <= 0)
412 xml_start_element (file, "parameters");
413 for (i = 0; i < g_callable_info_get_n_args (info); i++)
415 GIArgInfo *arg = g_callable_info_get_arg (info, i);
417 xml_start_element (file, "parameter");
418 xml_printf (file, " name=\"%s\"",
419 g_base_info_get_name ((GIBaseInfo *) arg));
421 switch (g_arg_info_get_ownership_transfer (arg))
423 case GI_TRANSFER_NOTHING:
425 case GI_TRANSFER_CONTAINER:
426 xml_printf (file, " transfer=\"container\"");
428 case GI_TRANSFER_EVERYTHING:
429 xml_printf (file, " transfer=\"full\"");
432 g_assert_not_reached ();
435 xml_printf (file, " direction=\"");
436 switch (g_arg_info_get_direction (arg))
438 case GI_DIRECTION_IN:
439 xml_printf (file, "in");
441 case GI_DIRECTION_OUT:
442 xml_printf (file, "out");
444 case GI_DIRECTION_INOUT:
445 xml_printf (file, "inout");
448 xml_printf (file, "\"");
450 if (g_arg_info_may_be_null (arg))
451 xml_printf (file, " null-ok=\"1\"");
453 if (g_arg_info_is_dipper (arg))
454 xml_printf (file, " dipper=\"1\"");
456 if (g_arg_info_is_return_value (arg))
457 xml_printf (file, " retval=\"1\"");
459 if (g_arg_info_is_optional (arg))
460 xml_printf (file, " optional=\"1\"");
462 type = g_arg_info_get_type (arg);
463 write_type_info (namespace, type, file);
465 xml_end_element (file, "parameter");
467 g_base_info_unref ((GIBaseInfo *)arg);
470 xml_end_element (file, "parameters");
471 g_base_info_unref ((GIBaseInfo *)type);
475 write_function_info (const gchar *namespace,
476 GIFunctionInfo *info,
479 GIFunctionInfoFlags flags;
485 flags = g_function_info_get_flags (info);
486 name = g_base_info_get_name ((GIBaseInfo *)info);
487 symbol = g_function_info_get_symbol (info);
488 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
490 if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
492 else if (flags & GI_FUNCTION_IS_METHOD)
497 xml_start_element (file, tag);
498 xml_printf (file, " name=\"%s\" c:identifier=\"%s\"",
501 if (flags & GI_FUNCTION_IS_SETTER)
502 xml_printf (file, " type=\"setter\"");
503 else if (flags & GI_FUNCTION_IS_GETTER)
504 xml_printf (file, " type=\"getter\"");
507 xml_printf (file, " deprecated=\"1\"");
509 write_callable_info (namespace, (GICallableInfo*)info, file);
510 xml_end_element (file, tag);
514 write_callback_info (const gchar *namespace,
515 GICallbackInfo *info,
521 name = g_base_info_get_name ((GIBaseInfo *)info);
522 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
524 xml_start_element (file, "callback");
525 xml_printf (file, " name=\"%s\"", name);
528 xml_printf (file, " deprecated=\"1\"");
530 write_callable_info (namespace, (GICallableInfo*)info, file);
531 xml_end_element (file, "callback");
535 write_struct_info (const gchar *namespace,
540 const gchar *type_name;
541 const gchar *type_init;
546 name = g_base_info_get_name ((GIBaseInfo *)info);
547 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
549 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
550 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
552 if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED)
554 xml_start_element (file, "glib:boxed");
555 xml_printf (file, " glib:name=\"%s\"", name);
559 xml_start_element (file, "record");
560 xml_printf (file, " name=\"%s\"", name);
563 if (type_name != NULL)
564 xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
567 xml_printf (file, " deprecated=\"1\"");
569 n_elts = g_struct_info_get_n_fields (info) + g_struct_info_get_n_methods (info);
572 for (i = 0; i < g_struct_info_get_n_fields (info); i++)
574 GIFieldInfo *field = g_struct_info_get_field (info, i);
575 write_field_info (namespace, field, NULL, file);
576 g_base_info_unref ((GIBaseInfo *)field);
579 for (i = 0; i < g_struct_info_get_n_methods (info); i++)
581 GIFunctionInfo *function = g_struct_info_get_method (info, i);
582 write_function_info (namespace, function, file);
583 g_base_info_unref ((GIBaseInfo *)function);
588 xml_end_element_unchecked (file);
592 write_value_info (const gchar *namespace,
600 name = g_base_info_get_name ((GIBaseInfo *)info);
601 value = g_value_info_get_value (info);
602 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
604 xml_start_element (file, "member");
605 xml_printf (file, " name=\"%s\" value=\"%ld\"", name, value);
608 xml_printf (file, " deprecated=\"1\"");
610 xml_end_element (file, "member");
614 write_constant_value (const gchar *namespace,
619 switch (g_type_info_get_tag (type))
621 case GI_TYPE_TAG_BOOLEAN:
622 xml_printf (file, "%d", value->v_boolean);
624 case GI_TYPE_TAG_INT8:
625 xml_printf (file, "%d", value->v_int8);
627 case GI_TYPE_TAG_UINT8:
628 xml_printf (file, "%d", value->v_uint8);
630 case GI_TYPE_TAG_INT16:
631 xml_printf (file, "%" G_GINT16_FORMAT, value->v_int16);
633 case GI_TYPE_TAG_UINT16:
634 xml_printf (file, "%" G_GUINT16_FORMAT, value->v_uint16);
636 case GI_TYPE_TAG_INT32:
637 xml_printf (file, "%" G_GINT32_FORMAT, value->v_int32);
639 case GI_TYPE_TAG_UINT32:
640 xml_printf (file, "%" G_GUINT32_FORMAT, value->v_uint32);
642 case GI_TYPE_TAG_INT64:
643 xml_printf (file, "%" G_GINT64_FORMAT, value->v_int64);
645 case GI_TYPE_TAG_UINT64:
646 xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64);
648 case GI_TYPE_TAG_INT:
649 xml_printf (file, "%d", value->v_int);
651 case GI_TYPE_TAG_UINT:
652 xml_printf (file, "%d", value->v_uint);
654 case GI_TYPE_TAG_LONG:
655 xml_printf (file, "%ld", value->v_long);
657 case GI_TYPE_TAG_ULONG:
658 xml_printf (file, "%ld", value->v_ulong);
660 case GI_TYPE_TAG_SSIZE:
661 xml_printf (file, "%zd", value->v_ssize);
663 case GI_TYPE_TAG_SIZE:
664 xml_printf (file, "%zd", value->v_size);
666 case GI_TYPE_TAG_FLOAT:
667 xml_printf (file, "%f", value->v_float);
669 case GI_TYPE_TAG_DOUBLE:
670 xml_printf (file, "%f", value->v_double);
672 case GI_TYPE_TAG_UTF8:
673 case GI_TYPE_TAG_FILENAME:
674 xml_printf (file, "%s", value->v_string);
677 g_assert_not_reached ();
682 write_constant_info (const gchar *namespace,
683 GIConstantInfo *info,
691 name = g_base_info_get_name ((GIBaseInfo *)info);
692 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
694 xml_start_element (file, "constant");
695 xml_printf (file, " name=\"%s\"", name);
697 type = g_constant_info_get_type (info);
698 xml_printf (file, " value=\"");
700 g_constant_info_get_value (info, &value);
701 write_constant_value (namespace, type, &value, file);
702 xml_printf (file, "\"");
704 write_type_info (namespace, type, file);
706 xml_end_element (file, "constant");
708 g_base_info_unref ((GIBaseInfo *)type);
713 write_enum_info (const gchar *namespace,
718 const gchar *type_name;
719 const gchar *type_init;
723 name = g_base_info_get_name ((GIBaseInfo *)info);
724 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
726 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
727 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
729 if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
730 xml_start_element (file, "enumeration");
732 xml_start_element (file, "bitfield");
733 xml_printf (file, " name=\"%s\"", name);
736 xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
739 xml_printf (file, " deprecated=\"1\"");
742 for (i = 0; i < g_enum_info_get_n_values (info); i++)
744 GIValueInfo *value = g_enum_info_get_value (info, i);
745 write_value_info (namespace, value, file);
746 g_base_info_unref ((GIBaseInfo *)value);
749 xml_end_element_unchecked (file);
753 write_signal_info (const gchar *namespace,
761 name = g_base_info_get_name ((GIBaseInfo *)info);
762 flags = g_signal_info_get_flags (info);
763 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
765 xml_start_element (file, "glib:signal");
766 xml_printf (file, " name=\"%s\"", name);
769 xml_printf (file, " deprecated=\"1\"");
771 if (flags & G_SIGNAL_RUN_FIRST)
772 xml_printf (file, " when=\"FIRST\"");
773 else if (flags & G_SIGNAL_RUN_LAST)
774 xml_printf (file, " when=\"LAST\"");
775 else if (flags & G_SIGNAL_RUN_CLEANUP)
776 xml_printf (file, " when=\"CLEANUP\"");
778 if (flags & G_SIGNAL_NO_RECURSE)
779 xml_printf (file, " no-recurse=\"1\"");
781 if (flags & G_SIGNAL_DETAILED)
782 xml_printf (file, " detailed=\"1\"");
784 if (flags & G_SIGNAL_ACTION)
785 xml_printf (file, " action=\"1\"");
787 if (flags & G_SIGNAL_NO_HOOKS)
788 xml_printf (file, " no-hooks=\"1\"");
790 write_callable_info (namespace, (GICallableInfo*)info, file);
792 xml_end_element (file, "glib:signal");
796 write_vfunc_info (const gchar *namespace,
800 GIVFuncInfoFlags flags;
805 name = g_base_info_get_name ((GIBaseInfo *)info);
806 flags = g_vfunc_info_get_flags (info);
807 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
808 offset = g_vfunc_info_get_offset (info);
810 xml_start_element (file, "vfunc");
811 xml_printf (file, " name=\"%s\"", name);
814 xml_printf (file, " deprecated=\"1\"");
816 if (flags & GI_VFUNC_MUST_CHAIN_UP)
817 xml_printf (file, " must-chain-up=\"1\"");
819 if (flags & GI_VFUNC_MUST_OVERRIDE)
820 xml_printf (file, " override=\"always\"");
821 else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE)
822 xml_printf (file, " override=\"never\"");
824 xml_printf (file, " offset=\"%d\"", offset);
826 write_callable_info (namespace, (GICallableInfo*)info, file);
828 xml_end_element (file, "vfunc");
832 write_property_info (const gchar *namespace,
833 GIPropertyInfo *info,
841 name = g_base_info_get_name ((GIBaseInfo *)info);
842 flags = g_property_info_get_flags (info);
843 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
845 xml_start_element (file, "property");
846 xml_printf (file, " name=\"%s\"", name);
849 xml_printf (file, " deprecated=\"1\"");
851 /* Properties are assumed to be read-only (see also girwriter.py) */
852 if (!(flags & G_PARAM_READABLE))
853 xml_printf (file, " readable=\"0\"");
854 if (flags & G_PARAM_WRITABLE)
855 xml_printf (file, " writable=\"1\"");
857 if (flags & G_PARAM_CONSTRUCT)
858 xml_printf (file, " construct=\"1\"");
860 if (flags & G_PARAM_CONSTRUCT_ONLY)
861 xml_printf (file, " construct-only=\"1\"");
863 type = g_property_info_get_type (info);
865 write_type_info (namespace, type, file);
867 xml_end_element (file, "property");
871 write_object_info (const gchar *namespace,
876 const gchar *type_name;
877 const gchar *type_init;
882 name = g_base_info_get_name ((GIBaseInfo *)info);
883 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
885 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
886 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
887 xml_start_element (file, "class");
888 xml_printf (file, " name=\"%s\"", name);
890 pnode = g_object_info_get_parent (info);
893 write_type_name_attribute (namespace, (GIBaseInfo *)pnode, "parent", file);
894 g_base_info_unref ((GIBaseInfo *)pnode);
897 xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
900 xml_printf (file, " deprecated=\"1\"");
903 if (g_object_info_get_n_interfaces (info) > 0)
905 for (i = 0; i < g_object_info_get_n_interfaces (info); i++)
907 GIInterfaceInfo *imp = g_object_info_get_interface (info, i);
908 xml_start_element (file, "implements");
909 write_type_name_attribute (namespace, (GIBaseInfo *)imp, "name", file);
910 xml_end_element (file, "implements");
911 g_base_info_unref ((GIBaseInfo*)imp);
915 for (i = 0; i < g_object_info_get_n_fields (info); i++)
917 GIFieldInfo *field = g_object_info_get_field (info, i);
918 write_field_info (namespace, field, NULL, file);
919 g_base_info_unref ((GIBaseInfo *)field);
922 for (i = 0; i < g_object_info_get_n_methods (info); i++)
924 GIFunctionInfo *function = g_object_info_get_method (info, i);
925 write_function_info (namespace, function, file);
926 g_base_info_unref ((GIBaseInfo *)function);
929 for (i = 0; i < g_object_info_get_n_properties (info); i++)
931 GIPropertyInfo *prop = g_object_info_get_property (info, i);
932 write_property_info (namespace, prop, file);
933 g_base_info_unref ((GIBaseInfo *)prop);
936 for (i = 0; i < g_object_info_get_n_signals (info); i++)
938 GISignalInfo *signal = g_object_info_get_signal (info, i);
939 write_signal_info (namespace, signal, file);
940 g_base_info_unref ((GIBaseInfo *)signal);
943 for (i = 0; i < g_object_info_get_n_vfuncs (info); i++)
945 GIVFuncInfo *vfunc = g_object_info_get_vfunc (info, i);
946 write_vfunc_info (namespace, vfunc, file);
947 g_base_info_unref ((GIBaseInfo *)vfunc);
950 for (i = 0; i < g_object_info_get_n_constants (info); i++)
952 GIConstantInfo *constant = g_object_info_get_constant (info, i);
953 write_constant_info (namespace, constant, file);
954 g_base_info_unref ((GIBaseInfo *)constant);
957 xml_end_element (file, "class");
961 write_interface_info (const gchar *namespace,
962 GIInterfaceInfo *info,
966 const gchar *type_name;
967 const gchar *type_init;
971 name = g_base_info_get_name ((GIBaseInfo *)info);
972 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
974 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
975 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
976 xml_start_element (file, "interface");
977 xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"",
978 name, type_name, type_init);
981 xml_printf (file, " deprecated=\"1\"");
984 if (g_interface_info_get_n_prerequisites (info) > 0)
986 xml_start_element (file, "requires");
987 for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++)
989 GIBaseInfo *req = g_interface_info_get_prerequisite (info, i);
991 if (g_base_info_get_type (req) == GI_INFO_TYPE_INTERFACE)
992 xml_start_element (file, "interface");
994 xml_start_element (file, "object");
995 write_type_name_attribute (namespace, req, "name", file);
996 xml_end_element_unchecked (file);
997 g_base_info_unref (req);
999 xml_end_element (file, "requires");
1002 for (i = 0; i < g_interface_info_get_n_methods (info); i++)
1004 GIFunctionInfo *function = g_interface_info_get_method (info, i);
1005 write_function_info (namespace, function, file);
1006 g_base_info_unref ((GIBaseInfo *)function);
1009 for (i = 0; i < g_interface_info_get_n_properties (info); i++)
1011 GIPropertyInfo *prop = g_interface_info_get_property (info, i);
1012 write_property_info (namespace, prop, file);
1013 g_base_info_unref ((GIBaseInfo *)prop);
1016 for (i = 0; i < g_interface_info_get_n_signals (info); i++)
1018 GISignalInfo *signal = g_interface_info_get_signal (info, i);
1019 write_signal_info (namespace, signal, file);
1020 g_base_info_unref ((GIBaseInfo *)signal);
1023 for (i = 0; i < g_interface_info_get_n_vfuncs (info); i++)
1025 GIVFuncInfo *vfunc = g_interface_info_get_vfunc (info, i);
1026 write_vfunc_info (namespace, vfunc, file);
1027 g_base_info_unref ((GIBaseInfo *)vfunc);
1030 for (i = 0; i < g_interface_info_get_n_constants (info); i++)
1032 GIConstantInfo *constant = g_interface_info_get_constant (info, i);
1033 write_constant_info (namespace, constant, file);
1034 g_base_info_unref ((GIBaseInfo *)constant);
1037 xml_end_element (file, "interface");
1041 write_error_domain_info (const gchar *namespace,
1042 GIErrorDomainInfo *info,
1046 const gchar *name, *quark;
1048 name = g_base_info_get_name ((GIBaseInfo *)info);
1049 quark = g_error_domain_info_get_quark (info);
1050 enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info);
1051 xml_start_element (file, "errordomain");
1052 xml_printf (file, " name=\"%s\" get-quark=\"%s\"",
1054 write_type_name_attribute (namespace, enum_, "codes", file);
1055 xml_end_element (file, "errordomain");
1056 g_base_info_unref (enum_);
1060 write_union_info (const gchar *namespace,
1065 const gchar *type_name;
1066 const gchar *type_init;
1067 gboolean deprecated;
1070 name = g_base_info_get_name ((GIBaseInfo *)info);
1071 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
1073 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
1074 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
1076 xml_start_element (file, "union");
1077 xml_printf (file, " name=\"%s\"", name);
1080 xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
1083 xml_printf (file, " deprecated=\"1\"");
1086 if (g_union_info_is_discriminated (info))
1091 offset = g_union_info_get_discriminator_offset (info);
1092 type = g_union_info_get_discriminator_type (info);
1094 xml_start_element (file, "discriminator");
1095 xml_printf (file, " offset=\"%d\" type=\"", offset);
1096 write_type_info (namespace, type, file);
1097 xml_end_element (file, "discriminator");
1098 g_base_info_unref ((GIBaseInfo *)type);
1101 for (i = 0; i < g_union_info_get_n_fields (info); i++)
1103 GIFieldInfo *field = g_union_info_get_field (info, i);
1104 GIConstantInfo *constant = g_union_info_get_discriminator (info, i);
1105 write_field_info (namespace, field, constant, file);
1106 g_base_info_unref ((GIBaseInfo *)field);
1108 g_base_info_unref ((GIBaseInfo *)constant);
1111 for (i = 0; i < g_union_info_get_n_methods (info); i++)
1113 GIFunctionInfo *function = g_union_info_get_method (info, i);
1114 write_function_info (namespace, function, file);
1115 g_base_info_unref ((GIBaseInfo *)function);
1118 xml_end_element (file, "union");
1122 write_repository (const char *namespace,
1123 gboolean needs_prefix)
1127 char **dependencies;
1128 GIRepository *repository;
1131 repository = g_irepository_get_default ();
1140 filename = g_strdup_printf ("%s-%s", namespace, output);
1142 filename = g_strdup (output);
1143 ofile = g_fopen (filename, "w");
1147 g_fprintf (stderr, "failed to open '%s': %s\n",
1148 filename, g_strerror (errno));
1157 xml = xml_open (ofile);
1159 xml_printf (xml, "<?xml version=\"1.0\"?>\n");
1160 xml_start_element (xml, "repository");
1161 xml_printf (xml, " version=\"1.0\"\n"
1162 " xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n"
1163 " xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n"
1164 " xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
1166 dependencies = g_irepository_get_dependencies (repository,
1168 if (dependencies != NULL)
1170 for (i = 0; dependencies[i]; i++)
1172 char **parts = g_strsplit (dependencies[i], "-", 2);
1173 xml_start_element (xml, "include");
1174 xml_printf (xml, " name=\"%s\" version=\"%s\"", parts[0], parts[1]);
1175 xml_end_element (xml, "include");
1182 const gchar *shared_library;
1183 const char *ns = namespace;
1184 const char *version;
1186 version = g_irepository_get_version (repository, ns);
1188 shared_library = g_irepository_get_shared_library (repository, ns);
1189 xml_start_element (xml, "namespace");
1190 xml_printf (xml, " name=\"%s\" version=\"%s\"", ns, version);
1192 xml_printf (xml, " shared-library=\"%s\"", shared_library);
1194 for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++)
1196 GIBaseInfo *info = g_irepository_get_info (repository, ns, j);
1197 switch (g_base_info_get_type (info))
1199 case GI_INFO_TYPE_FUNCTION:
1200 write_function_info (ns, (GIFunctionInfo *)info, xml);
1203 case GI_INFO_TYPE_CALLBACK:
1204 write_callback_info (ns, (GICallbackInfo *)info, xml);
1207 case GI_INFO_TYPE_STRUCT:
1208 case GI_INFO_TYPE_BOXED:
1209 write_struct_info (ns, (GIStructInfo *)info, xml);
1212 case GI_INFO_TYPE_UNION:
1213 write_union_info (ns, (GIUnionInfo *)info, xml);
1216 case GI_INFO_TYPE_ENUM:
1217 case GI_INFO_TYPE_FLAGS:
1218 write_enum_info (ns, (GIEnumInfo *)info, xml);
1221 case GI_INFO_TYPE_CONSTANT:
1222 write_constant_info (ns, (GIConstantInfo *)info, xml);
1225 case GI_INFO_TYPE_OBJECT:
1226 write_object_info (ns, (GIObjectInfo *)info, xml);
1229 case GI_INFO_TYPE_INTERFACE:
1230 write_interface_info (ns, (GIInterfaceInfo *)info, xml);
1233 case GI_INFO_TYPE_ERROR_DOMAIN:
1234 write_error_domain_info (ns, (GIErrorDomainInfo *)info, xml);
1238 g_error ("unknown info type %d\n", g_base_info_get_type (info));
1241 g_base_info_unref (info);
1244 xml_end_element (xml, "namespace");
1247 xml_end_element (xml, "repository");
1252 static const guchar *
1253 load_typelib (const gchar *filename,
1258 gsize *typelib_size;
1261 handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
1264 g_printerr ("Could not load typelib from '%s': %s\n",
1265 filename, g_module_error ());
1269 if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &typelib))
1271 g_printerr ("Could not load typelib from '%s': %s\n",
1272 filename, g_module_error ());
1276 if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &typelib_size))
1278 g_printerr ("Could not load typelib from '%s': %s\n",
1279 filename, g_module_error ());
1283 *len = *typelib_size;
1292 main (int argc, char *argv[])
1294 gboolean shlib = FALSE;
1295 gchar **input = NULL;
1296 GOptionContext *context;
1297 GError *error = NULL;
1298 gboolean needs_prefix;
1301 GOptionEntry options[] =
1303 { "shlib", 0, 0, G_OPTION_ARG_NONE, &shlib, "handle typelib embedded in shlib", NULL },
1304 { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" },
1305 { "includedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &includedirs, "include directories in GIR search path", NULL },
1306 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL },
1310 g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
1314 g_typelib_check_sanity ();
1316 context = g_option_context_new ("");
1317 g_option_context_add_main_entries (context, options, NULL);
1318 g_option_context_parse (context, &argc, &argv, &error);
1322 g_fprintf (stderr, "no input files\n");
1327 if (includedirs != NULL)
1328 for (i = 0; includedirs[i]; i++)
1329 g_irepository_prepend_search_path (includedirs[i]);
1331 for (i = 0; input[i]; i++)
1333 GModule *dlhandle = NULL;
1334 const guchar *typelib;
1336 const char *namespace;
1340 if (!g_file_get_contents (input[i], (gchar **)&typelib, &len, &error))
1342 g_fprintf (stderr, "failed to read '%s': %s\n",
1343 input[i], error->message);
1344 g_clear_error (&error);
1350 typelib = load_typelib (input[i], &dlhandle, &len);
1353 g_fprintf (stderr, "failed to load typelib from '%s'\n",
1359 if (input[i + 1] && output)
1360 needs_prefix = TRUE;
1362 needs_prefix = FALSE;
1364 data = g_typelib_new_from_const_memory (typelib, len);
1366 GError *error = NULL;
1367 if (!g_typelib_validate (data, &error)) {
1368 g_printerr ("typelib not valid: %s\n", error->message);
1369 g_clear_error (&error);
1373 namespace = g_irepository_load_typelib (g_irepository_get_default (), data, 0,
1375 if (namespace == NULL)
1377 g_printerr ("failed to load typelib: %s\n", error->message);
1381 write_repository (namespace, needs_prefix);
1385 g_module_close (dlhandle);
1389 /* when writing to stdout, stop after the first module */
1390 if (input[i + 1] && !output)
1392 g_fprintf (stderr, "warning, %d modules omitted\n",
1393 g_strv_length (input) - 1);