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_info (const gchar *namespace,
188 check_unresolved ((GIBaseInfo*)info);
190 tag = g_type_info_get_tag (info);
191 is_pointer = g_type_info_is_pointer (info);
193 if (tag == GI_TYPE_TAG_VOID)
196 xml_printf (file, "%s", "any");
198 xml_printf (file, "%s", "none");
200 else if (G_TYPE_TAG_IS_BASIC (tag))
201 xml_printf (file, "%s", g_type_tag_to_string (tag));
202 else if (tag == GI_TYPE_TAG_ARRAY)
206 type = g_type_info_get_param_type (info, 0);
207 write_type_info (namespace, type, file);
208 xml_printf (file, "[");
210 length = g_type_info_get_array_length (info);
213 xml_printf (file, "length=%d", length);
215 if (g_type_info_is_zero_terminated (info))
216 xml_printf (file, "%szero-terminated=1", length >= 0 ? "," : "");
218 xml_printf (file, "]");
219 g_base_info_unref ((GIBaseInfo *)type);
221 else if (tag == GI_TYPE_TAG_INTERFACE)
223 GIBaseInfo *iface = g_type_info_get_interface (info);
224 write_type_name (namespace, iface, file);
225 g_base_info_unref (iface);
227 else if (tag == GI_TYPE_TAG_GLIST)
229 type = g_type_info_get_param_type (info, 0);
230 xml_printf (file, "GLib.List");
233 xml_printf (file, "<");
234 write_type_info (namespace, type, file);
235 xml_printf (file, ">");
236 g_base_info_unref ((GIBaseInfo *)type);
239 else if (tag == GI_TYPE_TAG_GSLIST)
241 type = g_type_info_get_param_type (info, 0);
242 xml_printf (file, "GLib.SList");
245 xml_printf (file, "<");
246 write_type_info (namespace, type, file);
247 xml_printf (file, ">");
248 g_base_info_unref ((GIBaseInfo *)type);
251 else if (tag == GI_TYPE_TAG_GHASH)
253 type = g_type_info_get_param_type (info, 0);
254 xml_printf (file, "GLib.HashTable");
257 xml_printf (file, "<");
258 write_type_info (namespace, type, file);
259 g_base_info_unref ((GIBaseInfo *)type);
260 type = g_type_info_get_param_type (info, 1);
261 xml_printf (file, ",");
262 write_type_info (namespace, type, file);
263 xml_printf (file, ">");
264 g_base_info_unref ((GIBaseInfo *)type);
267 else if (tag == GI_TYPE_TAG_ERROR)
271 xml_printf (file, "GLib.Error");
272 n = g_type_info_get_n_error_domains (info);
275 xml_printf (file, "<");
276 for (i = 0; i < n; i++)
278 GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i);
280 xml_printf (file, ",");
281 write_type_name (namespace, (GIBaseInfo *)ed, file);
282 g_base_info_unref ((GIBaseInfo *)ed);
284 xml_printf (file, ">");
289 g_printerr ("Unhandled type tag %d\n", tag);
290 g_assert_not_reached ();
295 write_constant_value (const gchar *namespace,
301 write_field_info (const gchar *namespace,
303 GIConstantInfo *branch,
307 GIFieldInfoFlags flags;
313 name = g_base_info_get_name ((GIBaseInfo *)info);
314 flags = g_field_info_get_flags (info);
315 size = g_field_info_get_size (info);
316 offset = g_field_info_get_offset (info);
318 xml_start_element (file, "field");
319 xml_printf (file, " name=\"%s\" readable=\"%s\" writable=\"%s\"",
321 flags & GI_FIELD_IS_READABLE ? "1" : "0",
322 flags & GI_FIELD_IS_WRITABLE ? "1" : "0");
324 xml_printf (file, " bits=\"%d\"", size);
326 xml_printf (file, " offset=\"%d\"", offset);
328 type = g_field_info_get_type (info);
332 xml_printf (file, " branch=\"");
333 type = g_constant_info_get_type (branch);
334 g_constant_info_get_value (branch, &value);
335 write_constant_value (namespace, type, &value, file);
336 xml_printf (file, "\"");
339 xml_start_element (file, "type");
341 xml_printf (file, " name=\"");
343 write_type_info (namespace, type, file);
344 g_base_info_unref ((GIBaseInfo *)type);
346 xml_printf (file, "\"");
348 xml_end_element (file, "type");
350 xml_end_element (file, "field");
354 write_callable_info (const gchar *namespace,
355 GICallableInfo *info,
361 type = g_callable_info_get_return_type (info);
363 xml_start_element (file, "return-value");
365 if (g_type_info_is_pointer (type))
367 switch (g_callable_info_get_caller_owns (info))
369 case GI_TRANSFER_NOTHING:
371 case GI_TRANSFER_CONTAINER:
372 xml_printf (file, " transfer-ownership=\"container\"");
374 case GI_TRANSFER_EVERYTHING:
375 xml_printf (file, " transfer-ownership=\"full\"");
378 g_assert_not_reached ();
382 if (g_callable_info_may_return_null (info))
383 xml_printf (file, " null-ok=\"1\"");
385 xml_start_element (file, "type");
387 xml_printf (file, " name=\"");
389 write_type_info (namespace, type, file);
391 xml_printf (file, "\"");
393 xml_end_element (file, "type");
395 xml_end_element (file, "return-value");
397 if (g_callable_info_get_n_args (info) <= 0)
400 xml_start_element (file, "parameters");
401 for (i = 0; i < g_callable_info_get_n_args (info); i++)
403 GIArgInfo *arg = g_callable_info_get_arg (info, i);
405 xml_start_element (file, "parameter");
406 xml_printf (file, " name=\"%s\"",
407 g_base_info_get_name ((GIBaseInfo *) arg));
409 switch (g_arg_info_get_ownership_transfer (arg))
411 case GI_TRANSFER_NOTHING:
413 case GI_TRANSFER_CONTAINER:
414 xml_printf (file, " transfer=\"container\"");
416 case GI_TRANSFER_EVERYTHING:
417 xml_printf (file, " transfer=\"full\"");
420 g_assert_not_reached ();
423 xml_printf (file, " direction=\"");
424 switch (g_arg_info_get_direction (arg))
426 case GI_DIRECTION_IN:
427 xml_printf (file, "in");
429 case GI_DIRECTION_OUT:
430 xml_printf (file, "out");
432 case GI_DIRECTION_INOUT:
433 xml_printf (file, "inout");
436 xml_printf (file, "\"");
438 if (g_arg_info_may_be_null (arg))
439 xml_printf (file, " null-ok=\"1\"");
441 if (g_arg_info_is_dipper (arg))
442 xml_printf (file, " dipper=\"1\"");
444 if (g_arg_info_is_return_value (arg))
445 xml_printf (file, " retval=\"1\"");
447 if (g_arg_info_is_optional (arg))
448 xml_printf (file, " optional=\"1\"");
450 xml_start_element (file, "type");
452 xml_printf (file, " name=\"");
454 type = g_arg_info_get_type (arg);
455 write_type_info (namespace, type, file);
457 xml_printf (file, "\"");
459 xml_end_element (file, "type");
461 xml_end_element (file, "parameter");
463 g_base_info_unref ((GIBaseInfo *)arg);
466 xml_end_element (file, "parameters");
467 g_base_info_unref ((GIBaseInfo *)type);
471 write_function_info (const gchar *namespace,
472 GIFunctionInfo *info,
475 GIFunctionInfoFlags flags;
481 flags = g_function_info_get_flags (info);
482 name = g_base_info_get_name ((GIBaseInfo *)info);
483 symbol = g_function_info_get_symbol (info);
484 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
486 if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
488 else if (flags & GI_FUNCTION_IS_METHOD)
493 xml_start_element (file, tag);
494 xml_printf (file, " name=\"%s\" c:identifier=\"%s\"",
497 if (flags & GI_FUNCTION_IS_SETTER)
498 xml_printf (file, " type=\"setter\"");
499 else if (flags & GI_FUNCTION_IS_GETTER)
500 xml_printf (file, " type=\"getter\"");
503 xml_printf (file, " deprecated=\"1\"");
505 write_callable_info (namespace, (GICallableInfo*)info, file);
506 xml_end_element (file, tag);
510 write_callback_info (const gchar *namespace,
511 GICallbackInfo *info,
517 name = g_base_info_get_name ((GIBaseInfo *)info);
518 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
520 xml_start_element (file, "callback");
521 xml_printf (file, " name=\"%s\"", name);
524 xml_printf (file, " deprecated=\"1\"");
526 write_callable_info (namespace, (GICallableInfo*)info, file);
527 xml_end_element (file, "callback");
531 write_struct_info (const gchar *namespace,
536 const gchar *type_name;
537 const gchar *type_init;
542 name = g_base_info_get_name ((GIBaseInfo *)info);
543 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
545 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
546 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
548 if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED)
550 xml_start_element (file, "glib:boxed");
551 xml_printf (file, " glib:name=\"%s\"", name);
555 xml_start_element (file, "record");
556 xml_printf (file, " name=\"%s\"", name);
559 if (type_name != NULL)
560 xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
563 xml_printf (file, " deprecated=\"1\"");
565 n_elts = g_struct_info_get_n_fields (info) + g_struct_info_get_n_methods (info);
568 for (i = 0; i < g_struct_info_get_n_fields (info); i++)
570 GIFieldInfo *field = g_struct_info_get_field (info, i);
571 write_field_info (namespace, field, NULL, file);
572 g_base_info_unref ((GIBaseInfo *)field);
575 for (i = 0; i < g_struct_info_get_n_methods (info); i++)
577 GIFunctionInfo *function = g_struct_info_get_method (info, i);
578 write_function_info (namespace, function, file);
579 g_base_info_unref ((GIBaseInfo *)function);
584 xml_end_element_unchecked (file);
588 write_value_info (const gchar *namespace,
596 name = g_base_info_get_name ((GIBaseInfo *)info);
597 value = g_value_info_get_value (info);
598 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
600 xml_start_element (file, "member");
601 xml_printf (file, " name=\"%s\" value=\"%ld\"", name, value);
604 xml_printf (file, " deprecated=\"1\"");
606 xml_end_element (file, "member");
610 write_constant_value (const gchar *namespace,
615 switch (g_type_info_get_tag (type))
617 case GI_TYPE_TAG_BOOLEAN:
618 xml_printf (file, "%d", value->v_boolean);
620 case GI_TYPE_TAG_INT8:
621 xml_printf (file, "%d", value->v_int8);
623 case GI_TYPE_TAG_UINT8:
624 xml_printf (file, "%d", value->v_uint8);
626 case GI_TYPE_TAG_INT16:
627 xml_printf (file, "%" G_GINT16_FORMAT, value->v_int16);
629 case GI_TYPE_TAG_UINT16:
630 xml_printf (file, "%" G_GUINT16_FORMAT, value->v_uint16);
632 case GI_TYPE_TAG_INT32:
633 xml_printf (file, "%" G_GINT32_FORMAT, value->v_int32);
635 case GI_TYPE_TAG_UINT32:
636 xml_printf (file, "%" G_GUINT32_FORMAT, value->v_uint32);
638 case GI_TYPE_TAG_INT64:
639 xml_printf (file, "%" G_GINT64_FORMAT, value->v_int64);
641 case GI_TYPE_TAG_UINT64:
642 xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64);
644 case GI_TYPE_TAG_INT:
645 xml_printf (file, "%d", value->v_int);
647 case GI_TYPE_TAG_UINT:
648 xml_printf (file, "%d", value->v_uint);
650 case GI_TYPE_TAG_LONG:
651 xml_printf (file, "%ld", value->v_long);
653 case GI_TYPE_TAG_ULONG:
654 xml_printf (file, "%ld", value->v_ulong);
656 case GI_TYPE_TAG_SSIZE:
657 xml_printf (file, "%zd", value->v_ssize);
659 case GI_TYPE_TAG_SIZE:
660 xml_printf (file, "%zd", value->v_size);
662 case GI_TYPE_TAG_FLOAT:
663 xml_printf (file, "%f", value->v_float);
665 case GI_TYPE_TAG_DOUBLE:
666 xml_printf (file, "%f", value->v_double);
668 case GI_TYPE_TAG_UTF8:
669 case GI_TYPE_TAG_FILENAME:
670 xml_printf (file, "%s", value->v_string);
673 g_assert_not_reached ();
678 write_constant_info (const gchar *namespace,
679 GIConstantInfo *info,
687 name = g_base_info_get_name ((GIBaseInfo *)info);
688 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
690 xml_start_element (file, "constant");
691 xml_printf (file, " name=\"%s\"", name);
693 type = g_constant_info_get_type (info);
694 xml_printf (file, " value=\"");
696 g_constant_info_get_value (info, &value);
697 write_constant_value (namespace, type, &value, file);
698 xml_printf (file, "\"");
700 xml_start_element (file, "type");
701 xml_printf (file, " name=\"");
703 write_type_info (namespace, type, file);
704 xml_printf (file, "\"");
706 xml_end_element (file, "type");
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 if (flags & G_PARAM_READABLE)
854 xml_printf (file, " readable=\"1\"");
856 xml_printf (file, " readable=\"0\"");
858 if (flags & G_PARAM_WRITABLE)
859 xml_printf (file, " writable=\"1\"");
861 xml_printf (file, " writable=\"0\"");
863 if (flags & G_PARAM_CONSTRUCT)
864 xml_printf (file, " construct=\"1\"");
866 if (flags & G_PARAM_CONSTRUCT_ONLY)
867 xml_printf (file, " construct-only=\"1\"");
869 type = g_property_info_get_type (info);
871 xml_start_element (file, "type");
873 xml_printf (file, " name=\"");
875 write_type_info (namespace, type, file);
877 xml_printf (file, "\"");
879 xml_end_element (file, "type");
881 xml_end_element (file, "property");
885 write_object_info (const gchar *namespace,
890 const gchar *type_name;
891 const gchar *type_init;
896 name = g_base_info_get_name ((GIBaseInfo *)info);
897 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
899 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
900 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
901 xml_start_element (file, "class");
902 xml_printf (file, " name=\"%s\"", name);
904 pnode = g_object_info_get_parent (info);
907 xml_printf (file, " parent=\"");
908 write_type_name (namespace, (GIBaseInfo *)pnode, file);
909 xml_printf (file, "\"" );
910 g_base_info_unref ((GIBaseInfo *)pnode);
913 xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
916 xml_printf (file, " deprecated=\"1\"");
919 if (g_object_info_get_n_interfaces (info) > 0)
921 for (i = 0; i < g_object_info_get_n_interfaces (info); i++)
923 GIInterfaceInfo *imp = g_object_info_get_interface (info, i);
924 xml_start_element (file, "implements");
925 xml_printf (file, " name=\"");
926 write_type_name (namespace, (GIBaseInfo*)imp, file);
927 xml_printf (file,"\"");
928 xml_end_element (file, "implements");
929 g_base_info_unref ((GIBaseInfo*)imp);
933 for (i = 0; i < g_object_info_get_n_fields (info); i++)
935 GIFieldInfo *field = g_object_info_get_field (info, i);
936 write_field_info (namespace, field, NULL, file);
937 g_base_info_unref ((GIBaseInfo *)field);
940 for (i = 0; i < g_object_info_get_n_methods (info); i++)
942 GIFunctionInfo *function = g_object_info_get_method (info, i);
943 write_function_info (namespace, function, file);
944 g_base_info_unref ((GIBaseInfo *)function);
947 for (i = 0; i < g_object_info_get_n_properties (info); i++)
949 GIPropertyInfo *prop = g_object_info_get_property (info, i);
950 write_property_info (namespace, prop, file);
951 g_base_info_unref ((GIBaseInfo *)prop);
954 for (i = 0; i < g_object_info_get_n_signals (info); i++)
956 GISignalInfo *signal = g_object_info_get_signal (info, i);
957 write_signal_info (namespace, signal, file);
958 g_base_info_unref ((GIBaseInfo *)signal);
961 for (i = 0; i < g_object_info_get_n_vfuncs (info); i++)
963 GIVFuncInfo *vfunc = g_object_info_get_vfunc (info, i);
964 write_vfunc_info (namespace, vfunc, file);
965 g_base_info_unref ((GIBaseInfo *)vfunc);
968 for (i = 0; i < g_object_info_get_n_constants (info); i++)
970 GIConstantInfo *constant = g_object_info_get_constant (info, i);
971 write_constant_info (namespace, constant, file);
972 g_base_info_unref ((GIBaseInfo *)constant);
975 xml_end_element (file, "class");
979 write_interface_info (const gchar *namespace,
980 GIInterfaceInfo *info,
984 const gchar *type_name;
985 const gchar *type_init;
989 name = g_base_info_get_name ((GIBaseInfo *)info);
990 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
992 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
993 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
994 xml_start_element (file, "interface");
995 xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"",
996 name, type_name, type_init);
999 xml_printf (file, " deprecated=\"1\"");
1002 if (g_interface_info_get_n_prerequisites (info) > 0)
1004 xml_start_element (file, "requires");
1005 for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++)
1007 GIBaseInfo *req = g_interface_info_get_prerequisite (info, i);
1009 if (g_base_info_get_type (req) == GI_INFO_TYPE_INTERFACE)
1010 xml_start_element (file, "interface");
1012 xml_start_element (file, "object");
1013 xml_printf (file, " name=\"");
1014 write_type_name (namespace, req, file);
1015 xml_end_element_unchecked (file);
1016 g_base_info_unref (req);
1018 xml_end_element (file, "requires");
1021 for (i = 0; i < g_interface_info_get_n_methods (info); i++)
1023 GIFunctionInfo *function = g_interface_info_get_method (info, i);
1024 write_function_info (namespace, function, file);
1025 g_base_info_unref ((GIBaseInfo *)function);
1028 for (i = 0; i < g_interface_info_get_n_properties (info); i++)
1030 GIPropertyInfo *prop = g_interface_info_get_property (info, i);
1031 write_property_info (namespace, prop, file);
1032 g_base_info_unref ((GIBaseInfo *)prop);
1035 for (i = 0; i < g_interface_info_get_n_signals (info); i++)
1037 GISignalInfo *signal = g_interface_info_get_signal (info, i);
1038 write_signal_info (namespace, signal, file);
1039 g_base_info_unref ((GIBaseInfo *)signal);
1042 for (i = 0; i < g_interface_info_get_n_vfuncs (info); i++)
1044 GIVFuncInfo *vfunc = g_interface_info_get_vfunc (info, i);
1045 write_vfunc_info (namespace, vfunc, file);
1046 g_base_info_unref ((GIBaseInfo *)vfunc);
1049 for (i = 0; i < g_interface_info_get_n_constants (info); i++)
1051 GIConstantInfo *constant = g_interface_info_get_constant (info, i);
1052 write_constant_info (namespace, constant, file);
1053 g_base_info_unref ((GIBaseInfo *)constant);
1056 xml_end_element (file, "interface");
1060 write_error_domain_info (const gchar *namespace,
1061 GIErrorDomainInfo *info,
1065 const gchar *name, *quark;
1067 name = g_base_info_get_name ((GIBaseInfo *)info);
1068 quark = g_error_domain_info_get_quark (info);
1069 enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info);
1070 xml_start_element (file, "errordomain");
1071 xml_printf (file, " name=\"%s\" get-quark=\"%s\" codes=\"",
1073 write_type_name (namespace, enum_, file);
1074 xml_end_element (file, "errordomain");
1075 g_base_info_unref (enum_);
1079 write_union_info (const gchar *namespace,
1084 const gchar *type_name;
1085 const gchar *type_init;
1086 gboolean deprecated;
1089 name = g_base_info_get_name ((GIBaseInfo *)info);
1090 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
1092 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
1093 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
1095 xml_start_element (file, "union");
1096 xml_printf (file, " name=\"%s\"", name);
1099 xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
1102 xml_printf (file, " deprecated=\"1\"");
1105 if (g_union_info_is_discriminated (info))
1110 offset = g_union_info_get_discriminator_offset (info);
1111 type = g_union_info_get_discriminator_type (info);
1113 xml_start_element (file, "discriminator");
1114 xml_printf (file, " offset=\"%d\" type=\"", offset);
1115 write_type_info (namespace, type, file);
1116 xml_end_element (file, "discriminator");
1117 g_base_info_unref ((GIBaseInfo *)type);
1120 for (i = 0; i < g_union_info_get_n_fields (info); i++)
1122 GIFieldInfo *field = g_union_info_get_field (info, i);
1123 GIConstantInfo *constant = g_union_info_get_discriminator (info, i);
1124 write_field_info (namespace, field, constant, file);
1125 g_base_info_unref ((GIBaseInfo *)field);
1127 g_base_info_unref ((GIBaseInfo *)constant);
1130 for (i = 0; i < g_union_info_get_n_methods (info); i++)
1132 GIFunctionInfo *function = g_union_info_get_method (info, i);
1133 write_function_info (namespace, function, file);
1134 g_base_info_unref ((GIBaseInfo *)function);
1137 xml_end_element (file, "union");
1141 write_repository (const char *namespace,
1142 gboolean needs_prefix)
1147 char **dependencies;
1148 GIRepository *repository;
1151 repository = g_irepository_get_default ();
1160 filename = g_strdup_printf ("%s-%s", namespace, output);
1162 filename = g_strdup (output);
1163 ofile = g_fopen (filename, "w");
1167 g_fprintf (stderr, "failed to open '%s': %s\n",
1168 filename, g_strerror (errno));
1177 xml = xml_open (ofile);
1179 xml_printf (xml, "<?xml version=\"1.0\"?>\n");
1180 xml_start_element (xml, "repository");
1181 xml_printf (xml, " version=\"1.0\"\n"
1182 " xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n"
1183 " xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n"
1184 " xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
1186 dependencies = g_irepository_get_dependencies (repository,
1188 if (dependencies != NULL)
1190 for (i = 0; dependencies[i]; i++)
1192 xml_start_element (xml, "include");
1193 xml_printf (xml, " name=\"%s\"", dependencies[i]);
1194 xml_end_element (xml, "include");
1200 const gchar *shared_library;
1201 const char *ns = namespace;
1202 const char *version;
1204 version = g_irepository_get_version (repository, ns);
1206 shared_library = g_irepository_get_shared_library (repository, ns);
1207 xml_start_element (xml, "namespace");
1208 xml_printf (xml, " name=\"%s\" version=\"%s\"", ns, version);
1210 xml_printf (xml, " shared-library=\"%s\"", shared_library);
1212 for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++)
1214 GIBaseInfo *info = g_irepository_get_info (repository, ns, j);
1215 switch (g_base_info_get_type (info))
1217 case GI_INFO_TYPE_FUNCTION:
1218 write_function_info (ns, (GIFunctionInfo *)info, xml);
1221 case GI_INFO_TYPE_CALLBACK:
1222 write_callback_info (ns, (GICallbackInfo *)info, xml);
1225 case GI_INFO_TYPE_STRUCT:
1226 case GI_INFO_TYPE_BOXED:
1227 write_struct_info (ns, (GIStructInfo *)info, xml);
1230 case GI_INFO_TYPE_UNION:
1231 write_union_info (ns, (GIUnionInfo *)info, xml);
1234 case GI_INFO_TYPE_ENUM:
1235 case GI_INFO_TYPE_FLAGS:
1236 write_enum_info (ns, (GIEnumInfo *)info, xml);
1239 case GI_INFO_TYPE_CONSTANT:
1240 write_constant_info (ns, (GIConstantInfo *)info, xml);
1243 case GI_INFO_TYPE_OBJECT:
1244 write_object_info (ns, (GIObjectInfo *)info, xml);
1247 case GI_INFO_TYPE_INTERFACE:
1248 write_interface_info (ns, (GIInterfaceInfo *)info, xml);
1251 case GI_INFO_TYPE_ERROR_DOMAIN:
1252 write_error_domain_info (ns, (GIErrorDomainInfo *)info, xml);
1256 g_error ("unknown info type %d\n", g_base_info_get_type (info));
1259 g_base_info_unref (info);
1262 xml_end_element (xml, "namespace");
1265 xml_end_element (xml, "repository");
1270 static const guchar *
1271 load_typelib (const gchar *filename,
1276 gsize *typelib_size;
1279 handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
1282 g_printerr ("Could not load typelib from '%s': %s\n",
1283 filename, g_module_error ());
1287 if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &typelib))
1289 g_printerr ("Could not load typelib from '%s': %s\n",
1290 filename, g_module_error ());
1294 if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &typelib_size))
1296 g_printerr ("Could not load typelib from '%s': %s\n",
1297 filename, g_module_error ());
1301 *len = *typelib_size;
1310 main (int argc, char *argv[])
1312 gboolean shlib = FALSE;
1313 gchar **input = NULL;
1314 GOptionContext *context;
1315 GError *error = NULL;
1316 gboolean needs_prefix;
1319 GOptionEntry options[] =
1321 { "shlib", 0, 0, G_OPTION_ARG_NONE, &shlib, "handle typelib embedded in shlib", NULL },
1322 { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" },
1323 { "includedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &includedirs, "include directories in GIR search path", NULL },
1324 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL },
1328 g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
1332 g_typelib_check_sanity ();
1334 context = g_option_context_new ("");
1335 g_option_context_add_main_entries (context, options, NULL);
1336 g_option_context_parse (context, &argc, &argv, &error);
1340 g_fprintf (stderr, "no input files\n");
1345 if (includedirs != NULL)
1346 for (i = 0; includedirs[i]; i++)
1347 g_irepository_prepend_search_path (includedirs[i]);
1349 for (i = 0; input[i]; i++)
1351 GModule *dlhandle = NULL;
1352 const guchar *typelib;
1354 const char *namespace;
1358 if (!g_file_get_contents (input[i], (gchar **)&typelib, &len, &error))
1360 g_fprintf (stderr, "failed to read '%s': %s\n",
1361 input[i], error->message);
1362 g_clear_error (&error);
1368 typelib = load_typelib (input[i], &dlhandle, &len);
1371 g_fprintf (stderr, "failed to load typelib from '%s'\n",
1377 if (input[i + 1] && output)
1378 needs_prefix = TRUE;
1380 needs_prefix = FALSE;
1382 data = g_typelib_new_from_const_memory (typelib, len);
1384 GError *error = NULL;
1385 if (!g_typelib_validate (data, &error)) {
1386 g_printerr ("typelib not valid: %s\n", error->message);
1387 g_clear_error (&error);
1391 namespace = g_irepository_load_typelib (g_irepository_get_default (), data, 0,
1393 if (namespace == NULL)
1395 g_printerr ("failed to load typelib: %s\n", error->message);
1399 write_repository (namespace, needs_prefix);
1403 g_module_close (dlhandle);
1407 /* when writing to stdout, stop after the first module */
1408 if (input[i + 1] && !output)
1410 g_fprintf (stderr, "warning, %d modules omitted\n",
1411 g_strv_length (input) - 1);