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, ...)
70 vfprintf (xml->file, fmt, ap);
75 xml_start_element (Xml *xml, const char *element_name)
77 XmlElement *parent = NULL;
81 parent = xml->stack->data;
83 if (!parent->has_children)
84 xml_printf (xml, ">\n");
86 parent->has_children = TRUE;
89 xml_printf (xml, "%*s<%s", g_slist_length(xml->stack)*2, "", element_name);
91 xml->stack = g_slist_prepend (xml->stack, xml_element_new (element_name));
95 xml_end_element (Xml *xml, const char *name)
99 g_assert (xml->stack != NULL);
101 elem = xml->stack->data;
102 xml->stack = g_slist_delete_link (xml->stack, xml->stack);
105 g_assert_cmpstr (name, ==, elem->name);
107 if (elem->has_children)
108 xml_printf (xml, "%*s</%s>\n", g_slist_length (xml->stack)*2, "", elem->name);
110 xml_printf (xml, "/>\n");
112 xml_element_free (elem);
116 xml_end_element_unchecked (Xml *xml)
118 xml_end_element (xml, NULL);
122 xml_open (FILE *file)
126 xml = g_new (Xml, 1);
136 g_assert (xml->stack == NULL);
137 if (xml->file != NULL)
140 if (xml->file != stdout)
155 check_unresolved (GIBaseInfo *info)
157 if (g_base_info_get_type (info) != GI_INFO_TYPE_UNRESOLVED)
160 g_critical ("Found unresolved type '%s' '%s'\n",
161 g_base_info_get_name (info), g_base_info_get_namespace (info));
165 write_type_name (const gchar *namespace,
169 if (strcmp (namespace, g_base_info_get_namespace (info)) != 0)
170 xml_printf (file, "%s.", g_base_info_get_namespace (info));
172 xml_printf (file, "%s", g_base_info_get_name (info));
176 write_type_info (const gchar *namespace,
185 check_unresolved ((GIBaseInfo*)info);
187 tag = g_type_info_get_tag (info);
188 is_pointer = g_type_info_is_pointer (info);
190 if (tag == GI_TYPE_TAG_VOID)
193 xml_printf (file, "%s", "any");
195 xml_printf (file, "%s", "none");
197 else if (G_TYPE_TAG_IS_BASIC (tag))
198 xml_printf (file, "%s", g_type_tag_to_string (tag));
199 else if (tag == GI_TYPE_TAG_ARRAY)
203 type = g_type_info_get_param_type (info, 0);
204 write_type_info (namespace, type, file);
205 xml_printf (file, "[");
207 length = g_type_info_get_array_length (info);
210 xml_printf (file, "length=%d", length);
212 if (g_type_info_is_zero_terminated (info))
213 xml_printf (file, "%szero-terminated=1", length >= 0 ? "," : "");
215 xml_printf (file, "]");
216 g_base_info_unref ((GIBaseInfo *)type);
218 else if (tag == GI_TYPE_TAG_INTERFACE)
220 GIBaseInfo *iface = g_type_info_get_interface (info);
221 write_type_name (namespace, iface, file);
222 g_base_info_unref (iface);
224 else if (tag == GI_TYPE_TAG_GLIST)
226 type = g_type_info_get_param_type (info, 0);
227 xml_printf (file, "GLib.List");
230 xml_printf (file, "<");
231 write_type_info (namespace, type, file);
232 xml_printf (file, ">");
233 g_base_info_unref ((GIBaseInfo *)type);
236 else if (tag == GI_TYPE_TAG_GSLIST)
238 type = g_type_info_get_param_type (info, 0);
239 xml_printf (file, "GLib.SList");
242 xml_printf (file, "<");
243 write_type_info (namespace, type, file);
244 xml_printf (file, ">");
245 g_base_info_unref ((GIBaseInfo *)type);
248 else if (tag == GI_TYPE_TAG_GHASH)
250 type = g_type_info_get_param_type (info, 0);
251 xml_printf (file, "GLib.HashTable");
254 xml_printf (file, "<");
255 write_type_info (namespace, type, file);
256 g_base_info_unref ((GIBaseInfo *)type);
257 type = g_type_info_get_param_type (info, 1);
258 xml_printf (file, ",");
259 write_type_info (namespace, type, file);
260 xml_printf (file, ">");
261 g_base_info_unref ((GIBaseInfo *)type);
264 else if (tag == GI_TYPE_TAG_ERROR)
268 xml_printf (file, "GLib.Error");
269 n = g_type_info_get_n_error_domains (info);
272 xml_printf (file, "<");
273 for (i = 0; i < n; i++)
275 GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i);
277 xml_printf (file, ",");
278 write_type_name (namespace, (GIBaseInfo *)ed, file);
279 g_base_info_unref ((GIBaseInfo *)ed);
281 xml_printf (file, ">");
286 g_printerr ("Unhandled type tag %d\n", tag);
287 g_assert_not_reached ();
292 write_constant_value (const gchar *namespace,
298 write_field_info (const gchar *namespace,
300 GIConstantInfo *branch,
304 GIFieldInfoFlags flags;
310 name = g_base_info_get_name ((GIBaseInfo *)info);
311 flags = g_field_info_get_flags (info);
312 size = g_field_info_get_size (info);
313 offset = g_field_info_get_offset (info);
315 xml_start_element (file, "field");
316 xml_printf (file, " name=\"%s\" readable=\"%s\" writable=\"%s\"",
318 flags & GI_FIELD_IS_READABLE ? "1" : "0",
319 flags & GI_FIELD_IS_WRITABLE ? "1" : "0");
321 xml_printf (file, " bits=\"%d\"", size);
323 xml_printf (file, " offset=\"%d\"", offset);
325 type = g_field_info_get_type (info);
329 xml_printf (file, " branch=\"");
330 type = g_constant_info_get_type (branch);
331 g_constant_info_get_value (branch, &value);
332 write_constant_value (namespace, type, &value, file);
333 xml_printf (file, "\"");
336 xml_start_element (file, "type");
338 xml_printf (file, " name=\"");
340 write_type_info (namespace, type, file);
341 g_base_info_unref ((GIBaseInfo *)type);
343 xml_printf (file, "\"");
345 xml_end_element (file, "type");
347 xml_end_element (file, "field");
351 write_callable_info (const gchar *namespace,
352 GICallableInfo *info,
359 type = g_callable_info_get_return_type (info);
361 xml_start_element (file, "return-value");
363 if (g_type_info_is_pointer (type))
365 switch (g_callable_info_get_caller_owns (info))
367 case GI_TRANSFER_NOTHING:
369 case GI_TRANSFER_CONTAINER:
370 xml_printf (file, " transfer-ownership=\"container\"");
372 case GI_TRANSFER_EVERYTHING:
373 xml_printf (file, " transfer-ownership=\"full\"");
376 g_assert_not_reached ();
380 if (g_callable_info_may_return_null (info))
381 xml_printf (file, " null-ok=\"1\"");
383 xml_start_element (file, "type");
385 xml_printf (file, " name=\"");
387 write_type_info (namespace, type, file);
389 xml_printf (file, "\"");
391 xml_end_element (file, "type");
393 xml_end_element (file, "return-value");
395 if (g_callable_info_get_n_args (info) <= 0)
398 xml_start_element (file, "parameters");
399 for (i = 0; i < g_callable_info_get_n_args (info); i++)
401 GIArgInfo *arg = g_callable_info_get_arg (info, i);
403 xml_start_element (file, "parameter");
404 xml_printf (file, " name=\"%s\"",
405 g_base_info_get_name ((GIBaseInfo *) arg));
407 switch (g_arg_info_get_ownership_transfer (arg))
409 case GI_TRANSFER_NOTHING:
411 case GI_TRANSFER_CONTAINER:
412 xml_printf (file, " transfer=\"container\"");
414 case GI_TRANSFER_EVERYTHING:
415 xml_printf (file, " transfer=\"full\"");
418 g_assert_not_reached ();
421 xml_printf (file, " direction=\"");
422 switch (g_arg_info_get_direction (arg))
424 case GI_DIRECTION_IN:
425 xml_printf (file, "in");
427 case GI_DIRECTION_OUT:
428 xml_printf (file, "out");
430 case GI_DIRECTION_INOUT:
431 xml_printf (file, "inout");
434 xml_printf (file, "\"");
436 if (g_arg_info_may_be_null (arg))
437 xml_printf (file, " null-ok=\"1\"");
439 if (g_arg_info_is_dipper (arg))
440 xml_printf (file, " dipper=\"1\"");
442 if (g_arg_info_is_return_value (arg))
443 xml_printf (file, " retval=\"1\"");
445 if (g_arg_info_is_optional (arg))
446 xml_printf (file, " optional=\"1\"");
448 xml_start_element (file, "type");
450 xml_printf (file, " name=\"");
452 type = g_arg_info_get_type (arg);
453 write_type_info (namespace, type, file);
455 xml_printf (file, "\"");
457 xml_end_element (file, "type");
459 xml_end_element (file, "parameter");
461 g_base_info_unref ((GIBaseInfo *)arg);
464 xml_end_element (file, "parameters");
465 g_base_info_unref ((GIBaseInfo *)type);
469 write_function_info (const gchar *namespace,
470 GIFunctionInfo *info,
474 GIFunctionInfoFlags flags;
480 flags = g_function_info_get_flags (info);
481 name = g_base_info_get_name ((GIBaseInfo *)info);
482 symbol = g_function_info_get_symbol (info);
483 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
485 if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
487 else if (flags & GI_FUNCTION_IS_METHOD)
492 xml_start_element (file, tag);
493 xml_printf (file, " name=\"%s\" c:identifier=\"%s\"",
496 if (flags & GI_FUNCTION_IS_SETTER)
497 xml_printf (file, " type=\"setter\"");
498 else if (flags & GI_FUNCTION_IS_GETTER)
499 xml_printf (file, " type=\"getter\"");
502 xml_printf (file, " deprecated=\"1\"");
504 write_callable_info (namespace, (GICallableInfo*)info, file, indent);
505 xml_end_element (file, tag);
509 write_callback_info (const gchar *namespace,
510 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, indent);
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, 6);
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,
688 name = g_base_info_get_name ((GIBaseInfo *)info);
689 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
691 xml_start_element (file, "constant");
692 xml_printf (file, " name=\"%s\"", name);
694 type = g_constant_info_get_type (info);
695 xml_printf (file, " value=\"");
697 g_constant_info_get_value (info, &value);
698 write_constant_value (namespace, type, &value, file);
699 xml_printf (file, "\"");
701 xml_start_element (file, "type");
702 xml_printf (file, " name=\"");
704 write_type_info (namespace, type, file);
705 xml_printf (file, "\"");
707 xml_end_element (file, "type");
709 xml_end_element (file, "constant");
711 g_base_info_unref ((GIBaseInfo *)type);
716 write_enum_info (const gchar *namespace,
721 const gchar *type_name;
722 const gchar *type_init;
726 name = g_base_info_get_name ((GIBaseInfo *)info);
727 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
729 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
730 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
732 if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
733 xml_start_element (file, "enumeration");
735 xml_start_element (file, "bitfield");
736 xml_printf (file, " name=\"%s\"", name);
739 xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
742 xml_printf (file, " deprecated=\"1\"");
745 for (i = 0; i < g_enum_info_get_n_values (info); i++)
747 GIValueInfo *value = g_enum_info_get_value (info, i);
748 write_value_info (namespace, value, file);
749 g_base_info_unref ((GIBaseInfo *)value);
752 xml_end_element_unchecked (file);
756 write_signal_info (const gchar *namespace,
764 name = g_base_info_get_name ((GIBaseInfo *)info);
765 flags = g_signal_info_get_flags (info);
766 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
768 xml_start_element (file, "glib:signal");
769 xml_printf (file, " name=\"%s\"", name);
772 xml_printf (file, " deprecated=\"1\"");
774 if (flags & G_SIGNAL_RUN_FIRST)
775 xml_printf (file, " when=\"FIRST\"");
776 else if (flags & G_SIGNAL_RUN_LAST)
777 xml_printf (file, " when=\"LAST\"");
778 else if (flags & G_SIGNAL_RUN_CLEANUP)
779 xml_printf (file, " when=\"CLEANUP\"");
781 if (flags & G_SIGNAL_NO_RECURSE)
782 xml_printf (file, " no-recurse=\"1\"");
784 if (flags & G_SIGNAL_DETAILED)
785 xml_printf (file, " detailed=\"1\"");
787 if (flags & G_SIGNAL_ACTION)
788 xml_printf (file, " action=\"1\"");
790 if (flags & G_SIGNAL_NO_HOOKS)
791 xml_printf (file, " no-hooks=\"1\"");
793 write_callable_info (namespace, (GICallableInfo*)info, file, 6);
795 xml_end_element (file, "glib:signal");
799 write_vfunc_info (const gchar *namespace,
803 GIVFuncInfoFlags flags;
808 name = g_base_info_get_name ((GIBaseInfo *)info);
809 flags = g_vfunc_info_get_flags (info);
810 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
811 offset = g_vfunc_info_get_offset (info);
813 xml_start_element (file, "vfunc");
814 xml_printf (file, " name=\"%s\"", name);
817 xml_printf (file, " deprecated=\"1\"");
819 if (flags & GI_VFUNC_MUST_CHAIN_UP)
820 xml_printf (file, " must-chain-up=\"1\"");
822 if (flags & GI_VFUNC_MUST_OVERRIDE)
823 xml_printf (file, " override=\"always\"");
824 else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE)
825 xml_printf (file, " override=\"never\"");
827 xml_printf (file, " offset=\"%d\"", offset);
829 write_callable_info (namespace, (GICallableInfo*)info, file, 6);
831 xml_end_element (file, "vfunc");
835 write_property_info (const gchar *namespace,
836 GIPropertyInfo *info,
844 name = g_base_info_get_name ((GIBaseInfo *)info);
845 flags = g_property_info_get_flags (info);
846 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
848 xml_start_element (file, "property");
849 xml_printf (file, " name=\"%s\"", name);
852 xml_printf (file, " deprecated=\"1\"");
854 if (flags & G_PARAM_READABLE)
855 xml_printf (file, " readable=\"1\"");
857 xml_printf (file, " readable=\"0\"");
859 if (flags & G_PARAM_WRITABLE)
860 xml_printf (file, " writable=\"1\"");
862 xml_printf (file, " writable=\"0\"");
864 if (flags & G_PARAM_CONSTRUCT)
865 xml_printf (file, " construct=\"1\"");
867 if (flags & G_PARAM_CONSTRUCT_ONLY)
868 xml_printf (file, " construct-only=\"1\"");
870 type = g_property_info_get_type (info);
872 xml_start_element (file, "type");
874 xml_printf (file, " name=\"");
876 write_type_info (namespace, type, file);
878 xml_printf (file, "\"");
880 xml_end_element (file, "type");
882 xml_end_element (file, "property");
886 write_object_info (const gchar *namespace,
891 const gchar *type_name;
892 const gchar *type_init;
897 name = g_base_info_get_name ((GIBaseInfo *)info);
898 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
900 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
901 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
902 xml_start_element (file, "class");
903 xml_printf (file, " name=\"%s\"", name);
905 pnode = g_object_info_get_parent (info);
908 xml_printf (file, " parent=\"");
909 write_type_name (namespace, (GIBaseInfo *)pnode, file);
910 xml_printf (file, "\"" );
911 g_base_info_unref ((GIBaseInfo *)pnode);
914 xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
917 xml_printf (file, " deprecated=\"1\"");
920 if (g_object_info_get_n_interfaces (info) > 0)
922 for (i = 0; i < g_object_info_get_n_interfaces (info); i++)
924 GIInterfaceInfo *imp = g_object_info_get_interface (info, i);
925 xml_start_element (file, "implements");
926 xml_printf (file, " name=\"");
927 write_type_name (namespace, (GIBaseInfo*)imp, file);
928 xml_printf (file,"\"");
929 xml_end_element (file, "implements");
930 g_base_info_unref ((GIBaseInfo*)imp);
934 for (i = 0; i < g_object_info_get_n_fields (info); i++)
936 GIFieldInfo *field = g_object_info_get_field (info, i);
937 write_field_info (namespace, field, NULL, file);
938 g_base_info_unref ((GIBaseInfo *)field);
941 for (i = 0; i < g_object_info_get_n_methods (info); i++)
943 GIFunctionInfo *function = g_object_info_get_method (info, i);
944 write_function_info (namespace, function, file, 6);
945 g_base_info_unref ((GIBaseInfo *)function);
948 for (i = 0; i < g_object_info_get_n_properties (info); i++)
950 GIPropertyInfo *prop = g_object_info_get_property (info, i);
951 write_property_info (namespace, prop, file);
952 g_base_info_unref ((GIBaseInfo *)prop);
955 for (i = 0; i < g_object_info_get_n_signals (info); i++)
957 GISignalInfo *signal = g_object_info_get_signal (info, i);
958 write_signal_info (namespace, signal, file);
959 g_base_info_unref ((GIBaseInfo *)signal);
962 for (i = 0; i < g_object_info_get_n_vfuncs (info); i++)
964 GIVFuncInfo *vfunc = g_object_info_get_vfunc (info, i);
965 write_vfunc_info (namespace, vfunc, file);
966 g_base_info_unref ((GIBaseInfo *)vfunc);
969 for (i = 0; i < g_object_info_get_n_constants (info); i++)
971 GIConstantInfo *constant = g_object_info_get_constant (info, i);
972 write_constant_info (namespace, constant, file, 6);
973 g_base_info_unref ((GIBaseInfo *)constant);
976 xml_end_element (file, "class");
980 write_interface_info (const gchar *namespace,
981 GIInterfaceInfo *info,
985 const gchar *type_name;
986 const gchar *type_init;
990 name = g_base_info_get_name ((GIBaseInfo *)info);
991 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
993 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
994 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
995 xml_start_element (file, "interface");
996 xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"",
997 name, type_name, type_init);
1000 xml_printf (file, " deprecated=\"1\"");
1003 if (g_interface_info_get_n_prerequisites (info) > 0)
1005 xml_start_element (file, "requires");
1006 for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++)
1008 GIBaseInfo *req = g_interface_info_get_prerequisite (info, i);
1010 if (g_base_info_get_type (req) == GI_INFO_TYPE_INTERFACE)
1011 xml_start_element (file, "interface");
1013 xml_start_element (file, "object");
1014 xml_printf (file, " name=\"");
1015 write_type_name (namespace, req, file);
1016 xml_end_element_unchecked (file);
1017 g_base_info_unref (req);
1019 xml_end_element (file, "requires");
1022 for (i = 0; i < g_interface_info_get_n_methods (info); i++)
1024 GIFunctionInfo *function = g_interface_info_get_method (info, i);
1025 write_function_info (namespace, function, file, 6);
1026 g_base_info_unref ((GIBaseInfo *)function);
1029 for (i = 0; i < g_interface_info_get_n_properties (info); i++)
1031 GIPropertyInfo *prop = g_interface_info_get_property (info, i);
1032 write_property_info (namespace, prop, file);
1033 g_base_info_unref ((GIBaseInfo *)prop);
1036 for (i = 0; i < g_interface_info_get_n_signals (info); i++)
1038 GISignalInfo *signal = g_interface_info_get_signal (info, i);
1039 write_signal_info (namespace, signal, file);
1040 g_base_info_unref ((GIBaseInfo *)signal);
1043 for (i = 0; i < g_interface_info_get_n_vfuncs (info); i++)
1045 GIVFuncInfo *vfunc = g_interface_info_get_vfunc (info, i);
1046 write_vfunc_info (namespace, vfunc, file);
1047 g_base_info_unref ((GIBaseInfo *)vfunc);
1050 for (i = 0; i < g_interface_info_get_n_constants (info); i++)
1052 GIConstantInfo *constant = g_interface_info_get_constant (info, i);
1053 write_constant_info (namespace, constant, file, 6);
1054 g_base_info_unref ((GIBaseInfo *)constant);
1057 xml_end_element (file, "interface");
1061 write_error_domain_info (const gchar *namespace,
1062 GIErrorDomainInfo *info,
1066 const gchar *name, *quark;
1068 name = g_base_info_get_name ((GIBaseInfo *)info);
1069 quark = g_error_domain_info_get_quark (info);
1070 enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info);
1071 xml_start_element (file, "errordomain");
1072 xml_printf (file, " name=\"%s\" get-quark=\"%s\" codes=\"",
1074 write_type_name (namespace, enum_, file);
1075 xml_end_element (file, "errordomain");
1076 g_base_info_unref (enum_);
1080 write_union_info (const gchar *namespace,
1085 const gchar *type_name;
1086 const gchar *type_init;
1087 gboolean deprecated;
1090 name = g_base_info_get_name ((GIBaseInfo *)info);
1091 deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
1093 type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
1094 type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
1096 xml_start_element (file, "union");
1097 xml_printf (file, " name=\"%s\"", name);
1100 xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
1103 xml_printf (file, " deprecated=\"1\"");
1106 if (g_union_info_is_discriminated (info))
1111 offset = g_union_info_get_discriminator_offset (info);
1112 type = g_union_info_get_discriminator_type (info);
1114 xml_start_element (file, "discriminator");
1115 xml_printf (file, " offset=\"%d\" type=\"", offset);
1116 write_type_info (namespace, type, file);
1117 xml_end_element (file, "discriminator");
1118 g_base_info_unref ((GIBaseInfo *)type);
1121 for (i = 0; i < g_union_info_get_n_fields (info); i++)
1123 GIFieldInfo *field = g_union_info_get_field (info, i);
1124 GIConstantInfo *constant = g_union_info_get_discriminator (info, i);
1125 write_field_info (namespace, field, constant, file);
1126 g_base_info_unref ((GIBaseInfo *)field);
1128 g_base_info_unref ((GIBaseInfo *)constant);
1131 for (i = 0; i < g_union_info_get_n_methods (info); i++)
1133 GIFunctionInfo *function = g_union_info_get_method (info, i);
1134 write_function_info (namespace, function, file, 6);
1135 g_base_info_unref ((GIBaseInfo *)function);
1138 xml_end_element (file, "union");
1142 write_repository (const char *namespace,
1143 gboolean needs_prefix)
1148 char **dependencies;
1149 GIRepository *repository;
1152 repository = g_irepository_get_default ();
1161 filename = g_strdup_printf ("%s-%s", namespace, output);
1163 filename = g_strdup (output);
1164 ofile = g_fopen (filename, "w");
1168 g_fprintf (stderr, "failed to open '%s': %s\n",
1169 filename, g_strerror (errno));
1178 xml = xml_open (ofile);
1180 xml_printf (xml, "<?xml version=\"1.0\"?>\n");
1181 xml_start_element (xml, "repository");
1182 xml_printf (xml, " version=\"1.0\"\n"
1183 " xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n"
1184 " xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n"
1185 " xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
1187 dependencies = g_irepository_get_dependencies (repository,
1189 if (dependencies != NULL)
1191 for (i = 0; dependencies[i]; i++)
1193 xml_start_element (xml, "include");
1194 xml_printf (xml, " name=\"%s\"", dependencies[i]);
1195 xml_end_element (xml, "include");
1201 const gchar *shared_library;
1202 const char *ns = namespace;
1203 const char *version;
1205 version = g_irepository_get_version (repository, ns);
1207 shared_library = g_irepository_get_shared_library (repository, ns);
1208 xml_start_element (xml, "namespace");
1209 xml_printf (xml, " name=\"%s\" version=\"%s\"", ns, version);
1211 xml_printf (xml, " shared-library=\"%s\"", shared_library);
1213 for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++)
1215 GIBaseInfo *info = g_irepository_get_info (repository, ns, j);
1216 switch (g_base_info_get_type (info))
1218 case GI_INFO_TYPE_FUNCTION:
1219 write_function_info (ns, (GIFunctionInfo *)info, xml, 4);
1222 case GI_INFO_TYPE_CALLBACK:
1223 write_callback_info (ns, (GICallbackInfo *)info, xml, 4);
1226 case GI_INFO_TYPE_STRUCT:
1227 case GI_INFO_TYPE_BOXED:
1228 write_struct_info (ns, (GIStructInfo *)info, xml);
1231 case GI_INFO_TYPE_UNION:
1232 write_union_info (ns, (GIUnionInfo *)info, xml);
1235 case GI_INFO_TYPE_ENUM:
1236 case GI_INFO_TYPE_FLAGS:
1237 write_enum_info (ns, (GIEnumInfo *)info, xml);
1240 case GI_INFO_TYPE_CONSTANT:
1241 write_constant_info (ns, (GIConstantInfo *)info, xml, 4);
1244 case GI_INFO_TYPE_OBJECT:
1245 write_object_info (ns, (GIObjectInfo *)info, xml);
1248 case GI_INFO_TYPE_INTERFACE:
1249 write_interface_info (ns, (GIInterfaceInfo *)info, xml);
1252 case GI_INFO_TYPE_ERROR_DOMAIN:
1253 write_error_domain_info (ns, (GIErrorDomainInfo *)info, xml);
1257 g_error ("unknown info type %d\n", g_base_info_get_type (info));
1260 g_base_info_unref (info);
1263 xml_end_element (xml, "namespace");
1266 xml_end_element (xml, "repository");
1271 static const guchar *
1272 load_typelib (const gchar *filename,
1277 gsize *typelib_size;
1280 handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
1283 g_printerr ("Could not load typelib from '%s': %s\n",
1284 filename, g_module_error ());
1288 if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &typelib))
1290 g_printerr ("Could not load typelib from '%s': %s\n",
1291 filename, g_module_error ());
1295 if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &typelib_size))
1297 g_printerr ("Could not load typelib from '%s': %s\n",
1298 filename, g_module_error ());
1302 *len = *typelib_size;
1311 main (int argc, char *argv[])
1313 gboolean shlib = FALSE;
1314 gchar **input = NULL;
1315 GOptionContext *context;
1316 GError *error = NULL;
1317 gboolean needs_prefix;
1320 GOptionEntry options[] =
1322 { "shlib", 0, 0, G_OPTION_ARG_NONE, &shlib, "handle typelib embedded in shlib", NULL },
1323 { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" },
1324 { "includedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &includedirs, "include directories in GIR search path", NULL },
1325 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL },
1329 g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
1333 g_typelib_check_sanity ();
1335 context = g_option_context_new ("");
1336 g_option_context_add_main_entries (context, options, NULL);
1337 g_option_context_parse (context, &argc, &argv, &error);
1341 g_fprintf (stderr, "no input files\n");
1346 if (includedirs != NULL)
1347 for (i = 0; includedirs[i]; i++)
1348 g_irepository_prepend_search_path (includedirs[i]);
1350 for (i = 0; input[i]; i++)
1352 GModule *dlhandle = NULL;
1353 const guchar *typelib;
1355 const char *namespace;
1359 if (!g_file_get_contents (input[i], (gchar **)&typelib, &len, &error))
1361 g_fprintf (stderr, "failed to read '%s': %s\n",
1362 input[i], error->message);
1363 g_clear_error (&error);
1369 typelib = load_typelib (input[i], &dlhandle, &len);
1372 g_fprintf (stderr, "failed to load typelib from '%s'\n",
1378 if (input[i + 1] && output)
1379 needs_prefix = TRUE;
1381 needs_prefix = FALSE;
1383 data = g_typelib_new_from_const_memory (typelib, len);
1385 GError *error = NULL;
1386 if (!g_typelib_validate (data, &error)) {
1387 g_printerr ("typelib not valid: %s\n", error->message);
1388 g_clear_error (&error);
1392 namespace = g_irepository_load_typelib (g_irepository_get_default (), data, 0,
1394 if (namespace == NULL)
1396 g_printerr ("failed to load typelib: %s\n", error->message);
1400 write_repository (namespace, needs_prefix);
1404 g_module_close (dlhandle);
1408 /* when writing to stdout, stop after the first module */
1409 if (input[i + 1] && !output)
1411 g_fprintf (stderr, "warning, %d modules omitted\n",
1412 g_strv_length (input) - 1);