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);
228 xml_printf (file, " length=\"%d\"", length);
230 size = g_type_info_get_array_fixed_size (info);
232 xml_printf (file, " fixed-size=\"%d\"", size);
234 if (g_type_info_is_zero_terminated (info))
235 xml_printf (file, " zero-terminated=\"1\"");
237 write_type_info (namespace, type, file);
239 g_base_info_unref ((GIBaseInfo *)type);
241 xml_end_element (file, "array");
243 else if (tag == GI_TYPE_TAG_INTERFACE)
245 GIBaseInfo *iface = g_type_info_get_interface (info);
246 xml_start_element (file, "type");
247 write_type_name_attribute (namespace, iface, "name", file);
248 xml_end_element (file, "type");
249 g_base_info_unref (iface);
251 else if (tag == GI_TYPE_TAG_GLIST)
253 xml_start_element (file, "type");
254 xml_printf (file, " name=\"GLib.List\"");
255 type = g_type_info_get_param_type (info, 0);
258 write_type_info (namespace, type, file);
259 g_base_info_unref ((GIBaseInfo *)type);
261 xml_end_element (file, "type");
263 else if (tag == GI_TYPE_TAG_GSLIST)
265 xml_start_element (file, "type");
266 xml_printf (file, " name=\"GLib.SList\"");
267 type = g_type_info_get_param_type (info, 0);
270 write_type_info (namespace, type, file);
271 g_base_info_unref ((GIBaseInfo *)type);
273 xml_end_element (file, "type");
275 else if (tag == GI_TYPE_TAG_GHASH)
277 xml_start_element (file, "type");
278 xml_printf (file, " name=\"GLib.HashTable\"");
279 type = g_type_info_get_param_type (info, 0);
282 write_type_info (namespace, type, file);
283 g_base_info_unref ((GIBaseInfo *)type);
284 type = g_type_info_get_param_type (info, 1);
285 write_type_info (namespace, type, file);
286 g_base_info_unref ((GIBaseInfo *)type);
288 xml_end_element (file, "type");
290 else if (tag == GI_TYPE_TAG_ERROR)
294 xml_start_element (file, "type");
295 xml_printf (file, " name=\"GLib.Error\"");
297 n = g_type_info_get_n_error_domains (info);
300 for (i = 0; i < n; i++)
302 GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i);
303 xml_start_element (file, "type");
304 write_type_name_attribute (namespace, (GIBaseInfo *)ed, "name", file);
305 xml_end_element (file, "type");
306 g_base_info_unref ((GIBaseInfo *)ed);
310 xml_end_element (file, "type");
314 g_printerr ("Unhandled type tag %d\n", tag);
315 g_assert_not_reached ();
320 write_constant_value (const gchar *namespace,
326 write_field_info (const gchar *namespace,
328 GIConstantInfo *branch,
332 GIFieldInfoFlags flags;
338 name = g_base_info_get_name ((GIBaseInfo *)info);
339 flags = g_field_info_get_flags (info);
340 size = g_field_info_get_size (info);
341 offset = g_field_info_get_offset (info);
343 xml_start_element (file, "field");
344 xml_printf (file, " name=\"%s\"", name);
346 /* Fields are assumed to be read-only
347 * (see also girwriter.py and girparser.c)
349 if (!(flags & GI_FIELD_IS_READABLE))
350 xml_printf (file, " readable=\"0\"");
351 if (flags & GI_FIELD_IS_WRITABLE)
352 xml_printf (file, " writable=\"1\"");
355 xml_printf (file, " bits=\"%d\"", size);
357 type = g_field_info_get_type (info);
361 xml_printf (file, " branch=\"");
362 type = g_constant_info_get_type (branch);
363 g_constant_info_get_value (branch, &value);
364 write_constant_value (namespace, type, &value, file);
365 xml_printf (file, "\"");
368 write_type_info (namespace, type, file);
369 g_base_info_unref ((GIBaseInfo *)type);
371 xml_end_element (file, "field");
375 write_callable_info (const gchar *namespace,
376 GICallableInfo *info,
382 type = g_callable_info_get_return_type (info);
384 xml_start_element (file, "return-value");
386 switch (g_callable_info_get_caller_owns (info))
388 case GI_TRANSFER_NOTHING:
389 xml_printf (file, " transfer-ownership=\"none\"");
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 ();
401 if (g_callable_info_may_return_null (info))
402 xml_printf (file, " allow-none=\"1\"");
404 write_type_info (namespace, type, file);
406 xml_end_element (file, "return-value");
408 if (g_callable_info_get_n_args (info) <= 0)
411 xml_start_element (file, "parameters");
412 for (i = 0; i < g_callable_info_get_n_args (info); i++)
414 GIArgInfo *arg = g_callable_info_get_arg (info, i);
416 xml_start_element (file, "parameter");
417 xml_printf (file, " name=\"%s\"",
418 g_base_info_get_name ((GIBaseInfo *) arg));
420 switch (g_arg_info_get_ownership_transfer (arg))
422 case GI_TRANSFER_NOTHING:
423 xml_printf (file, " transfer-ownership=\"none\"");
425 case GI_TRANSFER_CONTAINER:
426 xml_printf (file, " transfer-ownership=\"container\"");
428 case GI_TRANSFER_EVERYTHING:
429 xml_printf (file, " transfer-ownership=\"full\"");
432 g_assert_not_reached ();
435 switch (g_arg_info_get_direction (arg))
437 case GI_DIRECTION_IN:
439 case GI_DIRECTION_OUT:
440 xml_printf (file, " direction=\"out\"");
442 case GI_DIRECTION_INOUT:
443 xml_printf (file, " direction=\"inout\"");
447 if (g_arg_info_may_be_null (arg))
448 xml_printf (file, " allow-none=\"1\"");
450 if (g_arg_info_is_dipper (arg))
451 xml_printf (file, " dipper=\"1\"");
453 if (g_arg_info_is_return_value (arg))
454 xml_printf (file, " retval=\"1\"");
456 if (g_arg_info_is_optional (arg))
457 xml_printf (file, " optional=\"1\"");
459 type = g_arg_info_get_type (arg);
460 write_type_info (namespace, type, file);
462 xml_end_element (file, "parameter");
464 g_base_info_unref ((GIBaseInfo *)arg);
467 xml_end_element (file, "parameters");
468 g_base_info_unref ((GIBaseInfo *)type);
472 write_function_info (const gchar *namespace,
473 GIFunctionInfo *info,
476 GIFunctionInfoFlags flags;
483 flags = g_function_info_get_flags (info);
484 name = g_base_info_get_name ((GIBaseInfo *)info);
485 symbol = g_function_info_get_symbol (info);
486 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
487 throws = flags & GI_FUNCTION_THROWS;
489 if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
491 else if (flags & GI_FUNCTION_IS_METHOD)
496 xml_start_element (file, tag);
497 xml_printf (file, " name=\"%s\" c:identifier=\"%s\"",
500 if (flags & GI_FUNCTION_IS_SETTER)
501 xml_printf (file, " type=\"setter\"");
502 else if (flags & GI_FUNCTION_IS_GETTER)
503 xml_printf (file, " type=\"getter\"");
506 xml_printf (file, " deprecated=\"1\"");
509 xml_printf (file, " throws=\"1\"");
511 write_callable_info (namespace, (GICallableInfo*)info, file);
512 xml_end_element (file, tag);
516 write_callback_info (const gchar *namespace,
517 GICallbackInfo *info,
523 name = g_base_info_get_name ((GIBaseInfo *)info);
524 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
526 xml_start_element (file, "callback");
527 xml_printf (file, " name=\"%s\"", name);
530 xml_printf (file, " deprecated=\"1\"");
532 write_callable_info (namespace, (GICallableInfo*)info, file);
533 xml_end_element (file, "callback");
537 write_struct_info (const gchar *namespace,
542 const gchar *type_name;
543 const gchar *type_init;
548 name = g_base_info_get_name ((GIBaseInfo *)info);
549 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
551 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
552 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
554 if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED)
556 xml_start_element (file, "glib:boxed");
557 xml_printf (file, " glib:name=\"%s\"", name);
561 xml_start_element (file, "record");
562 xml_printf (file, " name=\"%s\"", name);
565 if (type_name != NULL)
566 xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
569 xml_printf (file, " deprecated=\"1\"");
571 n_elts = g_struct_info_get_n_fields (info) + g_struct_info_get_n_methods (info);
574 for (i = 0; i < g_struct_info_get_n_fields (info); i++)
576 GIFieldInfo *field = g_struct_info_get_field (info, i);
577 write_field_info (namespace, field, NULL, file);
578 g_base_info_unref ((GIBaseInfo *)field);
581 for (i = 0; i < g_struct_info_get_n_methods (info); i++)
583 GIFunctionInfo *function = g_struct_info_get_method (info, i);
584 write_function_info (namespace, function, file);
585 g_base_info_unref ((GIBaseInfo *)function);
590 xml_end_element_unchecked (file);
594 write_value_info (const gchar *namespace,
602 name = g_base_info_get_name ((GIBaseInfo *)info);
603 value = g_value_info_get_value (info);
604 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
606 xml_start_element (file, "member");
607 xml_printf (file, " name=\"%s\" value=\"%ld\"", name, value);
610 xml_printf (file, " deprecated=\"1\"");
612 xml_end_element (file, "member");
616 write_constant_value (const gchar *namespace,
621 switch (g_type_info_get_tag (type))
623 case GI_TYPE_TAG_BOOLEAN:
624 xml_printf (file, "%d", value->v_boolean);
626 case GI_TYPE_TAG_INT8:
627 xml_printf (file, "%d", value->v_int8);
629 case GI_TYPE_TAG_UINT8:
630 xml_printf (file, "%d", value->v_uint8);
632 case GI_TYPE_TAG_INT16:
633 xml_printf (file, "%" G_GINT16_FORMAT, value->v_int16);
635 case GI_TYPE_TAG_UINT16:
636 xml_printf (file, "%" G_GUINT16_FORMAT, value->v_uint16);
638 case GI_TYPE_TAG_INT32:
639 xml_printf (file, "%" G_GINT32_FORMAT, value->v_int32);
641 case GI_TYPE_TAG_UINT32:
642 xml_printf (file, "%" G_GUINT32_FORMAT, value->v_uint32);
644 case GI_TYPE_TAG_INT64:
645 xml_printf (file, "%" G_GINT64_FORMAT, value->v_int64);
647 case GI_TYPE_TAG_UINT64:
648 xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64);
650 case GI_TYPE_TAG_INT:
651 xml_printf (file, "%d", value->v_int);
653 case GI_TYPE_TAG_UINT:
654 xml_printf (file, "%d", value->v_uint);
656 case GI_TYPE_TAG_LONG:
657 xml_printf (file, "%ld", value->v_long);
659 case GI_TYPE_TAG_ULONG:
660 xml_printf (file, "%ld", value->v_ulong);
662 case GI_TYPE_TAG_SSIZE:
663 xml_printf (file, "%zd", value->v_ssize);
665 case GI_TYPE_TAG_SIZE:
666 xml_printf (file, "%zd", value->v_size);
668 case GI_TYPE_TAG_FLOAT:
669 xml_printf (file, "%f", value->v_float);
671 case GI_TYPE_TAG_DOUBLE:
672 xml_printf (file, "%f", value->v_double);
674 case GI_TYPE_TAG_UTF8:
675 case GI_TYPE_TAG_FILENAME:
676 xml_printf (file, "%s", value->v_string);
679 g_assert_not_reached ();
684 write_constant_info (const gchar *namespace,
685 GIConstantInfo *info,
693 name = g_base_info_get_name ((GIBaseInfo *)info);
694 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
696 xml_start_element (file, "constant");
697 xml_printf (file, " name=\"%s\"", name);
699 type = g_constant_info_get_type (info);
700 xml_printf (file, " value=\"");
702 g_constant_info_get_value (info, &value);
703 write_constant_value (namespace, type, &value, file);
704 xml_printf (file, "\"");
706 write_type_info (namespace, type, file);
708 xml_end_element (file, "constant");
710 g_base_info_unref ((GIBaseInfo *)type);
715 write_enum_info (const gchar *namespace,
720 const gchar *type_name;
721 const gchar *type_init;
725 name = g_base_info_get_name ((GIBaseInfo *)info);
726 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
728 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
729 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
731 if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
732 xml_start_element (file, "enumeration");
734 xml_start_element (file, "bitfield");
735 xml_printf (file, " name=\"%s\"", name);
738 xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
741 xml_printf (file, " deprecated=\"1\"");
744 for (i = 0; i < g_enum_info_get_n_values (info); i++)
746 GIValueInfo *value = g_enum_info_get_value (info, i);
747 write_value_info (namespace, value, file);
748 g_base_info_unref ((GIBaseInfo *)value);
751 xml_end_element_unchecked (file);
755 write_signal_info (const gchar *namespace,
763 name = g_base_info_get_name ((GIBaseInfo *)info);
764 flags = g_signal_info_get_flags (info);
765 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
767 xml_start_element (file, "glib:signal");
768 xml_printf (file, " name=\"%s\"", name);
771 xml_printf (file, " deprecated=\"1\"");
773 if (flags & G_SIGNAL_RUN_FIRST)
774 xml_printf (file, " when=\"FIRST\"");
775 else if (flags & G_SIGNAL_RUN_LAST)
776 xml_printf (file, " when=\"LAST\"");
777 else if (flags & G_SIGNAL_RUN_CLEANUP)
778 xml_printf (file, " when=\"CLEANUP\"");
780 if (flags & G_SIGNAL_NO_RECURSE)
781 xml_printf (file, " no-recurse=\"1\"");
783 if (flags & G_SIGNAL_DETAILED)
784 xml_printf (file, " detailed=\"1\"");
786 if (flags & G_SIGNAL_ACTION)
787 xml_printf (file, " action=\"1\"");
789 if (flags & G_SIGNAL_NO_HOOKS)
790 xml_printf (file, " no-hooks=\"1\"");
792 write_callable_info (namespace, (GICallableInfo*)info, file);
794 xml_end_element (file, "glib:signal");
798 write_vfunc_info (const gchar *namespace,
802 GIVFuncInfoFlags flags;
807 name = g_base_info_get_name ((GIBaseInfo *)info);
808 flags = g_vfunc_info_get_flags (info);
809 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
810 offset = g_vfunc_info_get_offset (info);
812 xml_start_element (file, "vfunc");
813 xml_printf (file, " name=\"%s\"", name);
816 xml_printf (file, " deprecated=\"1\"");
818 if (flags & GI_VFUNC_MUST_CHAIN_UP)
819 xml_printf (file, " must-chain-up=\"1\"");
821 if (flags & GI_VFUNC_MUST_OVERRIDE)
822 xml_printf (file, " override=\"always\"");
823 else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE)
824 xml_printf (file, " override=\"never\"");
826 xml_printf (file, " offset=\"%d\"", offset);
828 write_callable_info (namespace, (GICallableInfo*)info, file);
830 xml_end_element (file, "vfunc");
834 write_property_info (const gchar *namespace,
835 GIPropertyInfo *info,
843 name = g_base_info_get_name ((GIBaseInfo *)info);
844 flags = g_property_info_get_flags (info);
845 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
847 xml_start_element (file, "property");
848 xml_printf (file, " name=\"%s\"", name);
851 xml_printf (file, " deprecated=\"1\"");
853 /* Properties are assumed to be read-only (see also girwriter.py) */
854 if (!(flags & G_PARAM_READABLE))
855 xml_printf (file, " readable=\"0\"");
856 if (flags & G_PARAM_WRITABLE)
857 xml_printf (file, " writable=\"1\"");
859 if (flags & G_PARAM_CONSTRUCT)
860 xml_printf (file, " construct=\"1\"");
862 if (flags & G_PARAM_CONSTRUCT_ONLY)
863 xml_printf (file, " construct-only=\"1\"");
865 type = g_property_info_get_type (info);
867 write_type_info (namespace, type, file);
869 xml_end_element (file, "property");
873 write_object_info (const gchar *namespace,
878 const gchar *type_name;
879 const gchar *type_init;
881 gboolean is_abstract;
885 name = g_base_info_get_name ((GIBaseInfo *)info);
886 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
887 is_abstract = g_object_info_get_abstract (info);
889 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
890 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
891 xml_start_element (file, "class");
892 xml_printf (file, " name=\"%s\"", name);
894 pnode = g_object_info_get_parent (info);
897 write_type_name_attribute (namespace, (GIBaseInfo *)pnode, "parent", file);
898 g_base_info_unref ((GIBaseInfo *)pnode);
902 xml_printf (file, " abstract=\"1\"");
904 xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
907 xml_printf (file, " deprecated=\"1\"");
910 if (g_object_info_get_n_interfaces (info) > 0)
912 for (i = 0; i < g_object_info_get_n_interfaces (info); i++)
914 GIInterfaceInfo *imp = g_object_info_get_interface (info, i);
915 xml_start_element (file, "implements");
916 write_type_name_attribute (namespace, (GIBaseInfo *)imp, "name", file);
917 xml_end_element (file, "implements");
918 g_base_info_unref ((GIBaseInfo*)imp);
922 for (i = 0; i < g_object_info_get_n_fields (info); i++)
924 GIFieldInfo *field = g_object_info_get_field (info, i);
925 write_field_info (namespace, field, NULL, file);
926 g_base_info_unref ((GIBaseInfo *)field);
929 for (i = 0; i < g_object_info_get_n_methods (info); i++)
931 GIFunctionInfo *function = g_object_info_get_method (info, i);
932 write_function_info (namespace, function, file);
933 g_base_info_unref ((GIBaseInfo *)function);
936 for (i = 0; i < g_object_info_get_n_properties (info); i++)
938 GIPropertyInfo *prop = g_object_info_get_property (info, i);
939 write_property_info (namespace, prop, file);
940 g_base_info_unref ((GIBaseInfo *)prop);
943 for (i = 0; i < g_object_info_get_n_signals (info); i++)
945 GISignalInfo *signal = g_object_info_get_signal (info, i);
946 write_signal_info (namespace, signal, file);
947 g_base_info_unref ((GIBaseInfo *)signal);
950 for (i = 0; i < g_object_info_get_n_vfuncs (info); i++)
952 GIVFuncInfo *vfunc = g_object_info_get_vfunc (info, i);
953 write_vfunc_info (namespace, vfunc, file);
954 g_base_info_unref ((GIBaseInfo *)vfunc);
957 for (i = 0; i < g_object_info_get_n_constants (info); i++)
959 GIConstantInfo *constant = g_object_info_get_constant (info, i);
960 write_constant_info (namespace, constant, file);
961 g_base_info_unref ((GIBaseInfo *)constant);
964 xml_end_element (file, "class");
968 write_interface_info (const gchar *namespace,
969 GIInterfaceInfo *info,
973 const gchar *type_name;
974 const gchar *type_init;
978 name = g_base_info_get_name ((GIBaseInfo *)info);
979 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
981 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
982 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
983 xml_start_element (file, "interface");
984 xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"",
985 name, type_name, type_init);
988 xml_printf (file, " deprecated=\"1\"");
991 if (g_interface_info_get_n_prerequisites (info) > 0)
993 xml_start_element (file, "requires");
994 for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++)
996 GIBaseInfo *req = g_interface_info_get_prerequisite (info, i);
998 if (g_base_info_get_type (req) == GI_INFO_TYPE_INTERFACE)
999 xml_start_element (file, "interface");
1001 xml_start_element (file, "object");
1002 write_type_name_attribute (namespace, req, "name", file);
1003 xml_end_element_unchecked (file);
1004 g_base_info_unref (req);
1006 xml_end_element (file, "requires");
1009 for (i = 0; i < g_interface_info_get_n_methods (info); i++)
1011 GIFunctionInfo *function = g_interface_info_get_method (info, i);
1012 write_function_info (namespace, function, file);
1013 g_base_info_unref ((GIBaseInfo *)function);
1016 for (i = 0; i < g_interface_info_get_n_properties (info); i++)
1018 GIPropertyInfo *prop = g_interface_info_get_property (info, i);
1019 write_property_info (namespace, prop, file);
1020 g_base_info_unref ((GIBaseInfo *)prop);
1023 for (i = 0; i < g_interface_info_get_n_signals (info); i++)
1025 GISignalInfo *signal = g_interface_info_get_signal (info, i);
1026 write_signal_info (namespace, signal, file);
1027 g_base_info_unref ((GIBaseInfo *)signal);
1030 for (i = 0; i < g_interface_info_get_n_vfuncs (info); i++)
1032 GIVFuncInfo *vfunc = g_interface_info_get_vfunc (info, i);
1033 write_vfunc_info (namespace, vfunc, file);
1034 g_base_info_unref ((GIBaseInfo *)vfunc);
1037 for (i = 0; i < g_interface_info_get_n_constants (info); i++)
1039 GIConstantInfo *constant = g_interface_info_get_constant (info, i);
1040 write_constant_info (namespace, constant, file);
1041 g_base_info_unref ((GIBaseInfo *)constant);
1044 xml_end_element (file, "interface");
1048 write_error_domain_info (const gchar *namespace,
1049 GIErrorDomainInfo *info,
1053 const gchar *name, *quark;
1055 name = g_base_info_get_name ((GIBaseInfo *)info);
1056 quark = g_error_domain_info_get_quark (info);
1057 enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info);
1058 xml_start_element (file, "errordomain");
1059 xml_printf (file, " name=\"%s\" get-quark=\"%s\"",
1061 write_type_name_attribute (namespace, enum_, "codes", file);
1062 xml_end_element (file, "errordomain");
1063 g_base_info_unref (enum_);
1067 write_union_info (const gchar *namespace,
1072 const gchar *type_name;
1073 const gchar *type_init;
1074 gboolean deprecated;
1077 name = g_base_info_get_name ((GIBaseInfo *)info);
1078 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
1080 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
1081 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
1083 xml_start_element (file, "union");
1084 xml_printf (file, " name=\"%s\"", name);
1087 xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
1090 xml_printf (file, " deprecated=\"1\"");
1093 if (g_union_info_is_discriminated (info))
1098 offset = g_union_info_get_discriminator_offset (info);
1099 type = g_union_info_get_discriminator_type (info);
1101 xml_start_element (file, "discriminator");
1102 xml_printf (file, " offset=\"%d\" type=\"", offset);
1103 write_type_info (namespace, type, file);
1104 xml_end_element (file, "discriminator");
1105 g_base_info_unref ((GIBaseInfo *)type);
1108 for (i = 0; i < g_union_info_get_n_fields (info); i++)
1110 GIFieldInfo *field = g_union_info_get_field (info, i);
1111 GIConstantInfo *constant = g_union_info_get_discriminator (info, i);
1112 write_field_info (namespace, field, constant, file);
1113 g_base_info_unref ((GIBaseInfo *)field);
1115 g_base_info_unref ((GIBaseInfo *)constant);
1118 for (i = 0; i < g_union_info_get_n_methods (info); i++)
1120 GIFunctionInfo *function = g_union_info_get_method (info, i);
1121 write_function_info (namespace, function, file);
1122 g_base_info_unref ((GIBaseInfo *)function);
1125 xml_end_element (file, "union");
1129 write_repository (const char *namespace,
1130 gboolean needs_prefix)
1134 char **dependencies;
1135 GIRepository *repository;
1138 repository = g_irepository_get_default ();
1147 filename = g_strdup_printf ("%s-%s", namespace, output);
1149 filename = g_strdup (output);
1150 ofile = g_fopen (filename, "w");
1154 g_fprintf (stderr, "failed to open '%s': %s\n",
1155 filename, g_strerror (errno));
1164 xml = xml_open (ofile);
1166 xml_printf (xml, "<?xml version=\"1.0\"?>\n");
1167 xml_start_element (xml, "repository");
1168 xml_printf (xml, " version=\"1.0\"\n"
1169 " xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n"
1170 " xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n"
1171 " xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
1173 dependencies = g_irepository_get_dependencies (repository,
1175 if (dependencies != NULL)
1177 for (i = 0; dependencies[i]; i++)
1179 char **parts = g_strsplit (dependencies[i], "-", 2);
1180 xml_start_element (xml, "include");
1181 xml_printf (xml, " name=\"%s\" version=\"%s\"", parts[0], parts[1]);
1182 xml_end_element (xml, "include");
1189 const gchar *shared_library;
1190 const char *ns = namespace;
1191 const char *version;
1193 version = g_irepository_get_version (repository, ns);
1195 shared_library = g_irepository_get_shared_library (repository, ns);
1196 xml_start_element (xml, "namespace");
1197 xml_printf (xml, " name=\"%s\" version=\"%s\"", ns, version);
1199 xml_printf (xml, " shared-library=\"%s\"", shared_library);
1201 for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++)
1203 GIBaseInfo *info = g_irepository_get_info (repository, ns, j);
1204 switch (g_base_info_get_type (info))
1206 case GI_INFO_TYPE_FUNCTION:
1207 write_function_info (ns, (GIFunctionInfo *)info, xml);
1210 case GI_INFO_TYPE_CALLBACK:
1211 write_callback_info (ns, (GICallbackInfo *)info, xml);
1214 case GI_INFO_TYPE_STRUCT:
1215 case GI_INFO_TYPE_BOXED:
1216 write_struct_info (ns, (GIStructInfo *)info, xml);
1219 case GI_INFO_TYPE_UNION:
1220 write_union_info (ns, (GIUnionInfo *)info, xml);
1223 case GI_INFO_TYPE_ENUM:
1224 case GI_INFO_TYPE_FLAGS:
1225 write_enum_info (ns, (GIEnumInfo *)info, xml);
1228 case GI_INFO_TYPE_CONSTANT:
1229 write_constant_info (ns, (GIConstantInfo *)info, xml);
1232 case GI_INFO_TYPE_OBJECT:
1233 write_object_info (ns, (GIObjectInfo *)info, xml);
1236 case GI_INFO_TYPE_INTERFACE:
1237 write_interface_info (ns, (GIInterfaceInfo *)info, xml);
1240 case GI_INFO_TYPE_ERROR_DOMAIN:
1241 write_error_domain_info (ns, (GIErrorDomainInfo *)info, xml);
1245 g_error ("unknown info type %d\n", g_base_info_get_type (info));
1248 g_base_info_unref (info);
1251 xml_end_element (xml, "namespace");
1254 xml_end_element (xml, "repository");
1259 static const guchar *
1260 load_typelib (const gchar *filename,
1265 gsize *typelib_size;
1268 handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
1271 g_printerr ("Could not load typelib from '%s': %s\n",
1272 filename, g_module_error ());
1276 if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &typelib))
1278 g_printerr ("Could not load typelib from '%s': %s\n",
1279 filename, g_module_error ());
1283 if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &typelib_size))
1285 g_printerr ("Could not load typelib from '%s': %s\n",
1286 filename, g_module_error ());
1290 *len = *typelib_size;
1299 main (int argc, char *argv[])
1301 gboolean shlib = FALSE;
1302 gchar **input = NULL;
1303 GOptionContext *context;
1304 GError *error = NULL;
1305 gboolean needs_prefix;
1308 GOptionEntry options[] =
1310 { "shlib", 0, 0, G_OPTION_ARG_NONE, &shlib, "handle typelib embedded in shlib", NULL },
1311 { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" },
1312 { "includedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &includedirs, "include directories in GIR search path", NULL },
1313 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL },
1317 g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
1321 g_typelib_check_sanity ();
1323 context = g_option_context_new ("");
1324 g_option_context_add_main_entries (context, options, NULL);
1325 g_option_context_parse (context, &argc, &argv, &error);
1329 g_fprintf (stderr, "no input files\n");
1334 if (includedirs != NULL)
1335 for (i = 0; includedirs[i]; i++)
1336 g_irepository_prepend_search_path (includedirs[i]);
1338 for (i = 0; input[i]; i++)
1340 GModule *dlhandle = NULL;
1341 const guchar *typelib;
1343 const char *namespace;
1347 if (!g_file_get_contents (input[i], (gchar **)&typelib, &len, &error))
1349 g_fprintf (stderr, "failed to read '%s': %s\n",
1350 input[i], error->message);
1351 g_clear_error (&error);
1357 typelib = load_typelib (input[i], &dlhandle, &len);
1360 g_fprintf (stderr, "failed to load typelib from '%s'\n",
1366 if (input[i + 1] && output)
1367 needs_prefix = TRUE;
1369 needs_prefix = FALSE;
1371 data = g_typelib_new_from_const_memory (typelib, len);
1373 GError *error = NULL;
1374 if (!g_typelib_validate (data, &error)) {
1375 g_printerr ("typelib not valid: %s\n", error->message);
1376 g_clear_error (&error);
1380 namespace = g_irepository_load_typelib (g_irepository_get_default (), data, 0,
1382 if (namespace == NULL)
1384 g_printerr ("failed to load typelib: %s\n", error->message);
1388 write_repository (namespace, needs_prefix);
1392 g_module_close (dlhandle);
1396 /* when writing to stdout, stop after the first module */
1397 if (input[i + 1] && !output)
1399 g_fprintf (stderr, "warning, %d modules omitted\n",
1400 g_strv_length (input) - 1);