diff options
author | Johan Dahlin <johan@gnome.org> | 2010-06-07 10:52:43 -0300 |
---|---|---|
committer | Johan Dahlin <johan@gnome.org> | 2010-06-07 10:52:43 -0300 |
commit | 0c550391b29da17446e22cebb1ccbacf8561983d (patch) | |
tree | d88b31fb9a184b8c5bd10341fe503946e87d58b5 | |
parent | e945a3cfdd3e599590075fe88f8c026ee96ce090 (diff) | |
download | gobject-introspection-0c550391b29da17446e22cebb1ccbacf8561983d.tar.gz |
[girwriter] Refactor out of generate.c
Move out the girwriter out of generate.c. Still a private API,
but that will probably change in the future.
-rw-r--r-- | girepository/Makefile.am | 4 | ||||
-rw-r--r-- | girepository/girwriter.c | 1402 | ||||
-rw-r--r-- | girepository/girwriter.h | 11 | ||||
-rw-r--r-- | tools/Makefile.am | 1 | ||||
-rw-r--r-- | tools/generate.c | 1369 |
5 files changed, 1418 insertions, 1369 deletions
diff --git a/girepository/Makefile.am b/girepository/Makefile.am index f85b5be5..f76e6c3e 100644 --- a/girepository/Makefile.am +++ b/girepository/Makefile.am @@ -64,6 +64,8 @@ libgirepository_parser_la_SOURCES = \ girnode.h \ giroffsets.c \ girparser.c \ - girparser.h + girparser.h \ + girwriter.c \ + girwriter.h libgirepository_parser_la_CFLAGS = $(GIREPO_CFLAGS) diff --git a/girepository/girwriter.c b/girepository/girwriter.c new file mode 100644 index 00000000..6fa892db --- /dev/null +++ b/girepository/girwriter.c @@ -0,0 +1,1402 @@ + +/* -*- Mode: C; c-file-style: "gnu"; -*- */ +/* GObject introspection: IDL generator + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <errno.h> +#include <string.h> +#include <stdio.h> + +#include <glib.h> +#include <glib-object.h> +#include <glib/gstdio.h> + +#include "girwriter.h" +#include "girepository.h" +#include "gitypelib-internal.h" + +typedef struct { + FILE *file; + GSList *stack; + gboolean show_all; +} Xml; + +typedef struct { + char *name; + guint has_children : 1; +} XmlElement; + +static XmlElement * +xml_element_new (const char *name) +{ + XmlElement *elem; + + elem = g_new (XmlElement, 1); + elem->name = g_strdup (name); + elem->has_children = FALSE; + return elem; +} + +static void +xml_element_free (XmlElement *elem) +{ + g_free (elem->name); + g_free (elem); +} + +static void +xml_printf (Xml *xml, const char *fmt, ...) +{ + va_list ap; + char *s; + + va_start (ap, fmt); + s = g_markup_vprintf_escaped (fmt, ap); + fputs (s, xml->file); + g_free (s); + va_end (ap); +} + +static void +xml_start_element (Xml *xml, const char *element_name) +{ + XmlElement *parent = NULL; + + if (xml->stack) + { + parent = xml->stack->data; + + if (!parent->has_children) + xml_printf (xml, ">\n"); + + parent->has_children = TRUE; + } + + xml_printf (xml, "%*s<%s", g_slist_length(xml->stack)*2, "", element_name); + + xml->stack = g_slist_prepend (xml->stack, xml_element_new (element_name)); +} + +static void +xml_end_element (Xml *xml, const char *name) +{ + XmlElement *elem; + + g_assert (xml->stack != NULL); + + elem = xml->stack->data; + xml->stack = g_slist_delete_link (xml->stack, xml->stack); + + if (name != NULL) + g_assert_cmpstr (name, ==, elem->name); + + if (elem->has_children) + xml_printf (xml, "%*s</%s>\n", g_slist_length (xml->stack)*2, "", elem->name); + else + xml_printf (xml, "/>\n"); + + xml_element_free (elem); +} + +static void +xml_end_element_unchecked (Xml *xml) +{ + xml_end_element (xml, NULL); +} + +static Xml * +xml_open (FILE *file) +{ + Xml *xml; + + xml = g_new (Xml, 1); + xml->file = file; + xml->stack = NULL; + + return xml; +} + +static void +xml_close (Xml *xml) +{ + g_assert (xml->stack == NULL); + if (xml->file != NULL) + { + fflush (xml->file); + if (xml->file != stdout) + fclose (xml->file); + xml->file = NULL; + } +} + +static void +xml_free (Xml *xml) +{ + xml_close (xml); + g_free (xml); +} + + +static void +check_unresolved (GIBaseInfo *info) +{ + if (g_base_info_get_type (info) != GI_INFO_TYPE_UNRESOLVED) + return; + + g_critical ("Found unresolved type '%s' '%s'\n", + g_base_info_get_name (info), g_base_info_get_namespace (info)); +} + +static void +write_type_name (const gchar *namespace, + GIBaseInfo *info, + Xml *file) +{ + if (strcmp (namespace, g_base_info_get_namespace (info)) != 0) + xml_printf (file, "%s.", g_base_info_get_namespace (info)); + + xml_printf (file, "%s", g_base_info_get_name (info)); +} + +static void +write_type_name_attribute (const gchar *namespace, + GIBaseInfo *info, + const char *attr_name, + Xml *file) +{ + xml_printf (file, " %s=\"", attr_name); + write_type_name (namespace, info, file); + xml_printf (file, "\""); +} + +static void +write_type_info (const gchar *namespace, + GITypeInfo *info, + Xml *file) +{ + gint tag; + gint i; + GITypeInfo *type; + gboolean is_pointer; + + check_unresolved ((GIBaseInfo*)info); + + tag = g_type_info_get_tag (info); + is_pointer = g_type_info_is_pointer (info); + + if (tag == GI_TYPE_TAG_VOID) + { + xml_start_element (file, "type"); + + xml_printf (file, " name=\"%s\"", is_pointer ? "any" : "none"); + + xml_end_element (file, "type"); + } + else if (G_TYPE_TAG_IS_BASIC (tag)) + { + xml_start_element (file, "type"); + xml_printf (file, " name=\"%s\"", g_type_tag_to_string (tag)); + xml_end_element (file, "type"); + } + else if (tag == GI_TYPE_TAG_ARRAY) + { + gint length, size; + char *name = NULL; + + xml_start_element (file, "array"); + + switch (g_type_info_get_array_type (info)) { + case GI_ARRAY_TYPE_C: + break; + case GI_ARRAY_TYPE_ARRAY: + name = "GLib.Array"; + break; + case GI_ARRAY_TYPE_PTR_ARRAY: + name = "GLib.PtrArray"; + break; + case GI_ARRAY_TYPE_BYTE_ARRAY: + name = "GLib.ByteArray"; + break; + default: + break; + } + + if (name) + xml_printf (file, " name=\"%s\"", name); + + type = g_type_info_get_param_type (info, 0); + + length = g_type_info_get_array_length (info); + if (length >= 0) + xml_printf (file, " length=\"%d\"", length); + + size = g_type_info_get_array_fixed_size (info); + if (size >= 0) + xml_printf (file, " fixed-size=\"%d\"", size); + + if (g_type_info_is_zero_terminated (info)) + xml_printf (file, " zero-terminated=\"1\""); + + write_type_info (namespace, type, file); + + g_base_info_unref ((GIBaseInfo *)type); + + xml_end_element (file, "array"); + } + else if (tag == GI_TYPE_TAG_INTERFACE) + { + GIBaseInfo *iface = g_type_info_get_interface (info); + xml_start_element (file, "type"); + write_type_name_attribute (namespace, iface, "name", file); + xml_end_element (file, "type"); + g_base_info_unref (iface); + } + else if (tag == GI_TYPE_TAG_GLIST) + { + xml_start_element (file, "type"); + xml_printf (file, " name=\"GLib.List\""); + type = g_type_info_get_param_type (info, 0); + if (type) + { + write_type_info (namespace, type, file); + g_base_info_unref ((GIBaseInfo *)type); + } + xml_end_element (file, "type"); + } + else if (tag == GI_TYPE_TAG_GSLIST) + { + xml_start_element (file, "type"); + xml_printf (file, " name=\"GLib.SList\""); + type = g_type_info_get_param_type (info, 0); + if (type) + { + write_type_info (namespace, type, file); + g_base_info_unref ((GIBaseInfo *)type); + } + xml_end_element (file, "type"); + } + else if (tag == GI_TYPE_TAG_GHASH) + { + xml_start_element (file, "type"); + xml_printf (file, " name=\"GLib.HashTable\""); + type = g_type_info_get_param_type (info, 0); + if (type) + { + write_type_info (namespace, type, file); + g_base_info_unref ((GIBaseInfo *)type); + type = g_type_info_get_param_type (info, 1); + write_type_info (namespace, type, file); + g_base_info_unref ((GIBaseInfo *)type); + } + xml_end_element (file, "type"); + } + else if (tag == GI_TYPE_TAG_ERROR) + { + gint n; + + xml_start_element (file, "type"); + xml_printf (file, " name=\"GLib.Error\""); + + n = g_type_info_get_n_error_domains (info); + if (n > 0) + { + for (i = 0; i < n; i++) + { + GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i); + xml_start_element (file, "type"); + write_type_name_attribute (namespace, (GIBaseInfo *)ed, "name", file); + xml_end_element (file, "type"); + g_base_info_unref ((GIBaseInfo *)ed); + } + } + + xml_end_element (file, "type"); + } + else + { + g_printerr ("Unhandled type tag %d\n", tag); + g_assert_not_reached (); + } +} + +static void +write_attributes (Xml *file, + GIBaseInfo *info) +{ + GIAttributeIter iter = { 0, }; + char *name, *value; + + while (g_base_info_iterate_attributes (info, &iter, &name, &value)) + { + xml_start_element (file, "attribute"); + xml_printf (file, " name=\"%s\" value=\"%s\"", name, value); + xml_end_element (file, "attribute"); + } +} + +static void +write_constant_value (const gchar *namespace, + GITypeInfo *info, + GArgument *argument, + Xml *file); + +static void +write_callback_info (const gchar *namespace, + GICallbackInfo *info, + Xml *file); + +static void +write_field_info (const gchar *namespace, + GIFieldInfo *info, + GIConstantInfo *branch, + Xml *file) +{ + const gchar *name; + GIFieldInfoFlags flags; + gint size; + gint offset; + GITypeInfo *type; + GIBaseInfo *interface; + GArgument value; + + name = g_base_info_get_name ((GIBaseInfo *)info); + flags = g_field_info_get_flags (info); + size = g_field_info_get_size (info); + offset = g_field_info_get_offset (info); + + xml_start_element (file, "field"); + xml_printf (file, " name=\"%s\"", name); + + /* Fields are assumed to be read-only + * (see also girwriter.py and girparser.c) + */ + if (!(flags & GI_FIELD_IS_READABLE)) + xml_printf (file, " readable=\"0\""); + if (flags & GI_FIELD_IS_WRITABLE) + xml_printf (file, " writable=\"1\""); + + if (size) + xml_printf (file, " bits=\"%d\"", size); + + write_attributes (file, (GIBaseInfo*) info); + + type = g_field_info_get_type (info); + + if (branch) + { + xml_printf (file, " branch=\""); + type = g_constant_info_get_type (branch); + g_constant_info_get_value (branch, &value); + write_constant_value (namespace, type, &value, file); + xml_printf (file, "\""); + } + + if (file->show_all) + { + if (offset >= 0) + xml_printf (file, "offset=\"%d\"", offset); + } + + interface = g_type_info_get_interface (type); + if (interface && g_base_info_get_type(interface) == GI_INFO_TYPE_CALLBACK) + write_callback_info (namespace, (GICallbackInfo *)interface, file); + else + write_type_info (namespace, type, file); + + if (interface) + g_base_info_unref (interface); + + g_base_info_unref ((GIBaseInfo *)type); + + xml_end_element (file, "field"); +} + +static void +write_callable_info (const gchar *namespace, + GICallableInfo *info, + Xml *file) +{ + GITypeInfo *type; + gint i; + + write_attributes (file, (GIBaseInfo*) info); + + type = g_callable_info_get_return_type (info); + + xml_start_element (file, "return-value"); + + switch (g_callable_info_get_caller_owns (info)) + { + case GI_TRANSFER_NOTHING: + xml_printf (file, " transfer-ownership=\"none\""); + break; + case GI_TRANSFER_CONTAINER: + xml_printf (file, " transfer-ownership=\"container\""); + break; + case GI_TRANSFER_EVERYTHING: + xml_printf (file, " transfer-ownership=\"full\""); + break; + default: + g_assert_not_reached (); + } + + if (g_callable_info_may_return_null (info)) + xml_printf (file, " allow-none=\"1\""); + + write_type_info (namespace, type, file); + + xml_end_element (file, "return-value"); + + if (g_callable_info_get_n_args (info) <= 0) + return; + + xml_start_element (file, "parameters"); + for (i = 0; i < g_callable_info_get_n_args (info); i++) + { + GIArgInfo *arg = g_callable_info_get_arg (info, i); + + xml_start_element (file, "parameter"); + xml_printf (file, " name=\"%s\"", + g_base_info_get_name ((GIBaseInfo *) arg)); + + switch (g_arg_info_get_ownership_transfer (arg)) + { + case GI_TRANSFER_NOTHING: + xml_printf (file, " transfer-ownership=\"none\""); + break; + case GI_TRANSFER_CONTAINER: + xml_printf (file, " transfer-ownership=\"container\""); + break; + case GI_TRANSFER_EVERYTHING: + xml_printf (file, " transfer-ownership=\"full\""); + break; + default: + g_assert_not_reached (); + } + + switch (g_arg_info_get_direction (arg)) + { + case GI_DIRECTION_IN: + break; + case GI_DIRECTION_OUT: + xml_printf (file, " direction=\"out\" caller-allocates=\"%s\"", + g_arg_info_is_caller_allocates (arg) ? "1" : "0"); + break; + case GI_DIRECTION_INOUT: + xml_printf (file, " direction=\"inout\""); + break; + } + + if (g_arg_info_may_be_null (arg)) + xml_printf (file, " allow-none=\"1\""); + + if (g_arg_info_is_return_value (arg)) + xml_printf (file, " retval=\"1\""); + + if (g_arg_info_is_optional (arg)) + xml_printf (file, " optional=\"1\""); + + switch (g_arg_info_get_scope (arg)) + { + case GI_SCOPE_TYPE_INVALID: + break; + case GI_SCOPE_TYPE_CALL: + xml_printf (file, " scope=\"call\""); + break; + case GI_SCOPE_TYPE_ASYNC: + xml_printf (file, " scope=\"async\""); + break; + case GI_SCOPE_TYPE_NOTIFIED: + xml_printf (file, " scope=\"notified\""); + break; + } + + if (g_arg_info_get_closure (arg) >= 0) + xml_printf (file, " closure=\"%d\"", g_arg_info_get_closure (arg)); + + if (g_arg_info_get_destroy (arg) >= 0) + xml_printf (file, " destroy=\"%d\"", g_arg_info_get_destroy (arg)); + + type = g_arg_info_get_type (arg); + write_type_info (namespace, type, file); + + xml_end_element (file, "parameter"); + + g_base_info_unref ((GIBaseInfo *)arg); + } + + xml_end_element (file, "parameters"); + g_base_info_unref ((GIBaseInfo *)type); +} + +static void +write_function_info (const gchar *namespace, + GIFunctionInfo *info, + Xml *file) +{ + GIFunctionInfoFlags flags; + const gchar *tag; + const gchar *name; + const gchar *symbol; + gboolean deprecated; + gboolean throws; + + flags = g_function_info_get_flags (info); + name = g_base_info_get_name ((GIBaseInfo *)info); + symbol = g_function_info_get_symbol (info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + throws = flags & GI_FUNCTION_THROWS; + + if (flags & GI_FUNCTION_IS_CONSTRUCTOR) + tag = "constructor"; + else if (flags & GI_FUNCTION_IS_METHOD) + tag = "method"; + else + tag = "function"; + + xml_start_element (file, tag); + xml_printf (file, " name=\"%s\" c:identifier=\"%s\"", + name, symbol); + + if (flags & GI_FUNCTION_IS_SETTER) + xml_printf (file, " type=\"setter\""); + else if (flags & GI_FUNCTION_IS_GETTER) + xml_printf (file, " type=\"getter\""); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + if (throws) + xml_printf (file, " throws=\"1\""); + + write_callable_info (namespace, (GICallableInfo*)info, file); + xml_end_element (file, tag); +} + +static void +write_callback_info (const gchar *namespace, + GICallbackInfo *info, + Xml *file) +{ + const gchar *name; + gboolean deprecated; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + xml_start_element (file, "callback"); + xml_printf (file, " name=\"%s\"", name); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + write_callable_info (namespace, (GICallableInfo*)info, file); + xml_end_element (file, "callback"); +} + +static void +write_struct_info (const gchar *namespace, + GIStructInfo *info, + Xml *file) +{ + const gchar *name; + const gchar *type_name; + const gchar *type_init; + gboolean deprecated; + gboolean is_gtype_struct; + gboolean foreign; + gint i; + gint size; + int n_elts; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); + type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); + + if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED) + { + xml_start_element (file, "glib:boxed"); + xml_printf (file, " glib:name=\"%s\"", name); + } + else + { + xml_start_element (file, "record"); + xml_printf (file, " name=\"%s\"", name); + } + + if (type_name != NULL) + xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + is_gtype_struct = g_struct_info_is_gtype_struct (info); + if (is_gtype_struct) + xml_printf (file, " glib:is-gtype-struct=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + size = g_struct_info_get_size (info); + if (file->show_all && size >= 0) + xml_printf (file, " size=\"%d\"", size); + + foreign = g_struct_info_is_foreign (info); + if (foreign) + xml_printf (file, " foreign=\"1\""); + + n_elts = g_struct_info_get_n_fields (info) + g_struct_info_get_n_methods (info); + if (n_elts > 0) + { + for (i = 0; i < g_struct_info_get_n_fields (info); i++) + { + GIFieldInfo *field = g_struct_info_get_field (info, i); + write_field_info (namespace, field, NULL, file); + g_base_info_unref ((GIBaseInfo *)field); + } + + for (i = 0; i < g_struct_info_get_n_methods (info); i++) + { + GIFunctionInfo *function = g_struct_info_get_method (info, i); + write_function_info (namespace, function, file); + g_base_info_unref ((GIBaseInfo *)function); + } + + } + + xml_end_element_unchecked (file); +} + +static void +write_value_info (const gchar *namespace, + GIValueInfo *info, + Xml *file) +{ + const gchar *name; + glong value; + gboolean deprecated; + + name = g_base_info_get_name ((GIBaseInfo *)info); + value = g_value_info_get_value (info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + xml_start_element (file, "member"); + xml_printf (file, " name=\"%s\" value=\"%ld\"", name, value); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + xml_end_element (file, "member"); +} + +static void +write_constant_value (const gchar *namespace, + GITypeInfo *type, + GArgument *value, + Xml *file) +{ + switch (g_type_info_get_tag (type)) + { + case GI_TYPE_TAG_BOOLEAN: + xml_printf (file, "%d", value->v_boolean); + break; + case GI_TYPE_TAG_INT8: + xml_printf (file, "%d", value->v_int8); + break; + case GI_TYPE_TAG_UINT8: + xml_printf (file, "%d", value->v_uint8); + break; + case GI_TYPE_TAG_INT16: + xml_printf (file, "%" G_GINT16_FORMAT, value->v_int16); + break; + case GI_TYPE_TAG_UINT16: + xml_printf (file, "%" G_GUINT16_FORMAT, value->v_uint16); + break; + case GI_TYPE_TAG_INT32: + xml_printf (file, "%" G_GINT32_FORMAT, value->v_int32); + break; + case GI_TYPE_TAG_UINT32: + xml_printf (file, "%" G_GUINT32_FORMAT, value->v_uint32); + break; + case GI_TYPE_TAG_INT64: + xml_printf (file, "%" G_GINT64_FORMAT, value->v_int64); + break; + case GI_TYPE_TAG_UINT64: + xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64); + break; + case GI_TYPE_TAG_INT: + xml_printf (file, "%d", value->v_int); + break; + case GI_TYPE_TAG_UINT: + xml_printf (file, "%d", value->v_uint); + break; + case GI_TYPE_TAG_LONG: + xml_printf (file, "%ld", value->v_long); + break; + case GI_TYPE_TAG_ULONG: + xml_printf (file, "%ld", value->v_ulong); + break; + case GI_TYPE_TAG_SSIZE: + xml_printf (file, "%zd", value->v_ssize); + break; + case GI_TYPE_TAG_SIZE: + xml_printf (file, "%zd", value->v_size); + break; + case GI_TYPE_TAG_FLOAT: + xml_printf (file, "%f", value->v_float); + break; + case GI_TYPE_TAG_DOUBLE: + xml_printf (file, "%f", value->v_double); + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + xml_printf (file, "%s", value->v_string); + break; + default: + g_assert_not_reached (); + } +} + +static void +write_constant_info (const gchar *namespace, + GIConstantInfo *info, + Xml *file) +{ + GITypeInfo *type; + const gchar *name; + gboolean deprecated; + GArgument value; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + xml_start_element (file, "constant"); + xml_printf (file, " name=\"%s\"", name); + + type = g_constant_info_get_type (info); + xml_printf (file, " value=\""); + + g_constant_info_get_value (info, &value); + write_constant_value (namespace, type, &value, file); + xml_printf (file, "\""); + + write_type_info (namespace, type, file); + + write_attributes (file, (GIBaseInfo*) info); + + xml_end_element (file, "constant"); + + g_base_info_unref ((GIBaseInfo *)type); +} + + +static void +write_enum_info (const gchar *namespace, + GIEnumInfo *info, + Xml *file) +{ + const gchar *name; + const gchar *type_name; + const gchar *type_init; + gboolean deprecated; + gint i; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); + type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); + + if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM) + xml_start_element (file, "enumeration"); + else + xml_start_element (file, "bitfield"); + xml_printf (file, " name=\"%s\"", name); + + if (type_init) + xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + for (i = 0; i < g_enum_info_get_n_values (info); i++) + { + GIValueInfo *value = g_enum_info_get_value (info, i); + write_value_info (namespace, value, file); + g_base_info_unref ((GIBaseInfo *)value); + } + + xml_end_element_unchecked (file); +} + +static void +write_signal_info (const gchar *namespace, + GISignalInfo *info, + Xml *file) +{ + GSignalFlags flags; + const gchar *name; + gboolean deprecated; + + name = g_base_info_get_name ((GIBaseInfo *)info); + flags = g_signal_info_get_flags (info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + xml_start_element (file, "glib:signal"); + xml_printf (file, " name=\"%s\"", name); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + if (flags & G_SIGNAL_RUN_FIRST) + xml_printf (file, " when=\"FIRST\""); + else if (flags & G_SIGNAL_RUN_LAST) + xml_printf (file, " when=\"LAST\""); + else if (flags & G_SIGNAL_RUN_CLEANUP) + xml_printf (file, " when=\"CLEANUP\""); + + if (flags & G_SIGNAL_NO_RECURSE) + xml_printf (file, " no-recurse=\"1\""); + + if (flags & G_SIGNAL_DETAILED) + xml_printf (file, " detailed=\"1\""); + + if (flags & G_SIGNAL_ACTION) + xml_printf (file, " action=\"1\""); + + if (flags & G_SIGNAL_NO_HOOKS) + xml_printf (file, " no-hooks=\"1\""); + + write_callable_info (namespace, (GICallableInfo*)info, file); + + xml_end_element (file, "glib:signal"); +} + +static void +write_vfunc_info (const gchar *namespace, + GIVFuncInfo *info, + Xml *file) +{ + GIVFuncInfoFlags flags; + const gchar *name; + GIFunctionInfo *invoker; + gboolean deprecated; + gint offset; + + name = g_base_info_get_name ((GIBaseInfo *)info); + flags = g_vfunc_info_get_flags (info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + offset = g_vfunc_info_get_offset (info); + invoker = g_vfunc_info_get_invoker (info); + + xml_start_element (file, "virtual-method"); + xml_printf (file, " name=\"%s\"", name); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + if (flags & GI_VFUNC_MUST_CHAIN_UP) + xml_printf (file, " must-chain-up=\"1\""); + + if (flags & GI_VFUNC_MUST_OVERRIDE) + xml_printf (file, " override=\"always\""); + else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE) + xml_printf (file, " override=\"never\""); + + xml_printf (file, " offset=\"%d\"", offset); + + if (invoker) + xml_printf (file, " invoker=\"%s\"", g_base_info_get_name ((GIBaseInfo*)invoker)); + + write_callable_info (namespace, (GICallableInfo*)info, file); + + xml_end_element (file, "virtual-method"); +} + +static void +write_property_info (const gchar *namespace, + GIPropertyInfo *info, + Xml *file) +{ + GParamFlags flags; + const gchar *name; + gboolean deprecated; + GITypeInfo *type; + + name = g_base_info_get_name ((GIBaseInfo *)info); + flags = g_property_info_get_flags (info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + xml_start_element (file, "property"); + xml_printf (file, " name=\"%s\"", name); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + /* Properties are assumed to be read-only (see also girwriter.py) */ + if (!(flags & G_PARAM_READABLE)) + xml_printf (file, " readable=\"0\""); + if (flags & G_PARAM_WRITABLE) + xml_printf (file, " writable=\"1\""); + + if (flags & G_PARAM_CONSTRUCT) + xml_printf (file, " construct=\"1\""); + + if (flags & G_PARAM_CONSTRUCT_ONLY) + xml_printf (file, " construct-only=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + type = g_property_info_get_type (info); + + write_type_info (namespace, type, file); + + xml_end_element (file, "property"); +} + +static void +write_object_info (const gchar *namespace, + GIObjectInfo *info, + Xml *file) +{ + const gchar *name; + const gchar *type_name; + const gchar *type_init; + gboolean deprecated; + gboolean is_abstract; + GIObjectInfo *pnode; + GIStructInfo *class_struct; + gint i; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + is_abstract = g_object_info_get_abstract (info); + + type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); + type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); + xml_start_element (file, "class"); + xml_printf (file, " name=\"%s\"", name); + + pnode = g_object_info_get_parent (info); + if (pnode) + { + write_type_name_attribute (namespace, (GIBaseInfo *)pnode, "parent", file); + g_base_info_unref ((GIBaseInfo *)pnode); + } + + class_struct = g_object_info_get_class_struct (info); + if (class_struct) + { + write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file); + g_base_info_unref ((GIBaseInfo*)class_struct); + } + + if (is_abstract) + xml_printf (file, " abstract=\"1\""); + + xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + if (g_object_info_get_n_interfaces (info) > 0) + { + for (i = 0; i < g_object_info_get_n_interfaces (info); i++) + { + GIInterfaceInfo *imp = g_object_info_get_interface (info, i); + xml_start_element (file, "implements"); + write_type_name_attribute (namespace, (GIBaseInfo *)imp, "name", file); + xml_end_element (file, "implements"); + g_base_info_unref ((GIBaseInfo*)imp); + } + } + + for (i = 0; i < g_object_info_get_n_fields (info); i++) + { + GIFieldInfo *field = g_object_info_get_field (info, i); + write_field_info (namespace, field, NULL, file); + g_base_info_unref ((GIBaseInfo *)field); + } + + for (i = 0; i < g_object_info_get_n_methods (info); i++) + { + GIFunctionInfo *function = g_object_info_get_method (info, i); + write_function_info (namespace, function, file); + g_base_info_unref ((GIBaseInfo *)function); + } + + for (i = 0; i < g_object_info_get_n_properties (info); i++) + { + GIPropertyInfo *prop = g_object_info_get_property (info, i); + write_property_info (namespace, prop, file); + g_base_info_unref ((GIBaseInfo *)prop); + } + + for (i = 0; i < g_object_info_get_n_signals (info); i++) + { + GISignalInfo *signal = g_object_info_get_signal (info, i); + write_signal_info (namespace, signal, file); + g_base_info_unref ((GIBaseInfo *)signal); + } + + for (i = 0; i < g_object_info_get_n_vfuncs (info); i++) + { + GIVFuncInfo *vfunc = g_object_info_get_vfunc (info, i); + write_vfunc_info (namespace, vfunc, file); + g_base_info_unref ((GIBaseInfo *)vfunc); + } + + for (i = 0; i < g_object_info_get_n_constants (info); i++) + { + GIConstantInfo *constant = g_object_info_get_constant (info, i); + write_constant_info (namespace, constant, file); + g_base_info_unref ((GIBaseInfo *)constant); + } + + xml_end_element (file, "class"); +} + +static void +write_interface_info (const gchar *namespace, + GIInterfaceInfo *info, + Xml *file) +{ + const gchar *name; + const gchar *type_name; + const gchar *type_init; + GIStructInfo *class_struct; + gboolean deprecated; + gint i; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); + type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); + xml_start_element (file, "interface"); + xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"", + name, type_name, type_init); + + class_struct = g_interface_info_get_iface_struct (info); + if (class_struct) + { + write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file); + g_base_info_unref ((GIBaseInfo*)class_struct); + } + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + if (g_interface_info_get_n_prerequisites (info) > 0) + { + for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++) + { + GIBaseInfo *req = g_interface_info_get_prerequisite (info, i); + + xml_start_element (file, "prerequisite"); + write_type_name_attribute (namespace, req, "name", file); + + xml_end_element_unchecked (file); + g_base_info_unref (req); + } + } + + for (i = 0; i < g_interface_info_get_n_methods (info); i++) + { + GIFunctionInfo *function = g_interface_info_get_method (info, i); + write_function_info (namespace, function, file); + g_base_info_unref ((GIBaseInfo *)function); + } + + for (i = 0; i < g_interface_info_get_n_properties (info); i++) + { + GIPropertyInfo *prop = g_interface_info_get_property (info, i); + write_property_info (namespace, prop, file); + g_base_info_unref ((GIBaseInfo *)prop); + } + + for (i = 0; i < g_interface_info_get_n_signals (info); i++) + { + GISignalInfo *signal = g_interface_info_get_signal (info, i); + write_signal_info (namespace, signal, file); + g_base_info_unref ((GIBaseInfo *)signal); + } + + for (i = 0; i < g_interface_info_get_n_vfuncs (info); i++) + { + GIVFuncInfo *vfunc = g_interface_info_get_vfunc (info, i); + write_vfunc_info (namespace, vfunc, file); + g_base_info_unref ((GIBaseInfo *)vfunc); + } + + for (i = 0; i < g_interface_info_get_n_constants (info); i++) + { + GIConstantInfo *constant = g_interface_info_get_constant (info, i); + write_constant_info (namespace, constant, file); + g_base_info_unref ((GIBaseInfo *)constant); + } + + xml_end_element (file, "interface"); +} + +static void +write_error_domain_info (const gchar *namespace, + GIErrorDomainInfo *info, + Xml *file) +{ + GIBaseInfo *enum_; + const gchar *name, *quark; + + name = g_base_info_get_name ((GIBaseInfo *)info); + quark = g_error_domain_info_get_quark (info); + enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info); + xml_start_element (file, "errordomain"); + xml_printf (file, " name=\"%s\" get-quark=\"%s\"", + name, quark); + write_type_name_attribute (namespace, enum_, "codes", file); + xml_end_element (file, "errordomain"); + g_base_info_unref (enum_); +} + +static void +write_union_info (const gchar *namespace, + GIUnionInfo *info, + Xml *file) +{ + const gchar *name; + const gchar *type_name; + const gchar *type_init; + gboolean deprecated; + gint i; + gint size; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); + type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); + + xml_start_element (file, "union"); + xml_printf (file, " name=\"%s\"", name); + + if (type_name) + xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + size = g_union_info_get_size (info); + if (file->show_all && size >= 0) + xml_printf (file, " size=\"%d\"", size); + + write_attributes (file, (GIBaseInfo*) info); + + if (g_union_info_is_discriminated (info)) + { + gint offset; + GITypeInfo *type; + + offset = g_union_info_get_discriminator_offset (info); + type = g_union_info_get_discriminator_type (info); + + xml_start_element (file, "discriminator"); + xml_printf (file, " offset=\"%d\" type=\"", offset); + write_type_info (namespace, type, file); + xml_end_element (file, "discriminator"); + g_base_info_unref ((GIBaseInfo *)type); + } + + for (i = 0; i < g_union_info_get_n_fields (info); i++) + { + GIFieldInfo *field = g_union_info_get_field (info, i); + GIConstantInfo *constant = g_union_info_get_discriminator (info, i); + write_field_info (namespace, field, constant, file); + g_base_info_unref ((GIBaseInfo *)field); + if (constant) + g_base_info_unref ((GIBaseInfo *)constant); + } + + for (i = 0; i < g_union_info_get_n_methods (info); i++) + { + GIFunctionInfo *function = g_union_info_get_method (info, i); + write_function_info (namespace, function, file); + g_base_info_unref ((GIBaseInfo *)function); + } + + xml_end_element (file, "union"); +} + + +/** + * gir_writer_write: + * @filename: filename to write to + * @namespace: GIR namespace to write + * @needs_prefix: + * @show_all: + * + * Writes the output of a typelib represented by @namespace + * into a GIR xml file named @filename. + */ +void +gir_writer_write (const char *filename, + const char *namespace, + gboolean needs_prefix, + gboolean show_all) +{ + FILE *ofile; + gint i, j; + char **dependencies; + GIRepository *repository; + Xml *xml; + + repository = g_irepository_get_default (); + + if (filename == NULL) + ofile = stdout; + else + { + gchar *full_filename; + + if (needs_prefix) + full_filename = g_strdup_printf ("%s-%s", namespace, filename); + else + full_filename = g_strdup (filename); + ofile = g_fopen (filename, "w"); + + if (ofile == NULL) + { + g_fprintf (stderr, "failed to open '%s': %s\n", + full_filename, g_strerror (errno)); + g_free (full_filename); + + return; + } + + g_free (full_filename); + } + + xml = xml_open (ofile); + xml->show_all = show_all; + xml_printf (xml, "<?xml version=\"1.0\"?>\n"); + xml_start_element (xml, "repository"); + xml_printf (xml, " version=\"1.0\"\n" + " xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n" + " xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n" + " xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\""); + + dependencies = g_irepository_get_dependencies (repository, + namespace); + if (dependencies != NULL) + { + for (i = 0; dependencies[i]; i++) + { + char **parts = g_strsplit (dependencies[i], "-", 2); + xml_start_element (xml, "include"); + xml_printf (xml, " name=\"%s\" version=\"%s\"", parts[0], parts[1]); + xml_end_element (xml, "include"); + g_strfreev (parts); + } + } + + if (TRUE) + { + const gchar *shared_library; + const gchar *c_prefix; + const char *ns = namespace; + const char *version; + + version = g_irepository_get_version (repository, ns); + + shared_library = g_irepository_get_shared_library (repository, ns); + c_prefix = g_irepository_get_c_prefix (repository, ns); + xml_start_element (xml, "namespace"); + xml_printf (xml, " name=\"%s\" version=\"%s\"", ns, version); + if (shared_library) + xml_printf (xml, " shared-library=\"%s\"", shared_library); + if (c_prefix) + xml_printf (xml, " c:prefix=\"%s\"", c_prefix); + + for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++) + { + GIBaseInfo *info = g_irepository_get_info (repository, ns, j); + switch (g_base_info_get_type (info)) + { + case GI_INFO_TYPE_FUNCTION: + write_function_info (ns, (GIFunctionInfo *)info, xml); + break; + + case GI_INFO_TYPE_CALLBACK: + write_callback_info (ns, (GICallbackInfo *)info, xml); + break; + + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_BOXED: + write_struct_info (ns, (GIStructInfo *)info, xml); + break; + + case GI_INFO_TYPE_UNION: + write_union_info (ns, (GIUnionInfo *)info, xml); + break; + + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + write_enum_info (ns, (GIEnumInfo *)info, xml); + break; + + case GI_INFO_TYPE_CONSTANT: + write_constant_info (ns, (GIConstantInfo *)info, xml); + break; + + case GI_INFO_TYPE_OBJECT: + write_object_info (ns, (GIObjectInfo *)info, xml); + break; + + case GI_INFO_TYPE_INTERFACE: + write_interface_info (ns, (GIInterfaceInfo *)info, xml); + break; + + case GI_INFO_TYPE_ERROR_DOMAIN: + write_error_domain_info (ns, (GIErrorDomainInfo *)info, xml); + break; + + default: + g_error ("unknown info type %d\n", g_base_info_get_type (info)); + } + + g_base_info_unref (info); + } + + xml_end_element (xml, "namespace"); + } + + xml_end_element (xml, "repository"); + + xml_free (xml); +} diff --git a/girepository/girwriter.h b/girepository/girwriter.h index 5d41a0c6..3ca7418b 100644 --- a/girepository/girwriter.h +++ b/girepository/girwriter.h @@ -18,9 +18,12 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __G_IDL_WRITER_H__ -#define __G_IDL_WRITER_H__ +#ifndef __GIRWRITER_H__ +#define __GIRWRITER_H__ -void g_idl_writer_save_file (GIdlModule *module, const gchar *filename); +void gir_writer_write (const char *filename, + const char *namespace, + gboolean needs_prefix, + gboolean show_all); -#endif /* __G_IDL_WRITER_H__ */ +#endif /* __GIRWRITER_H__ */ diff --git a/tools/Makefile.am b/tools/Makefile.am index ba0fa9f7..31acd022 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -20,6 +20,7 @@ g_ir_compiler_LDADD = \ g_ir_generate_SOURCES = generate.c g_ir_generate_CFLAGS = $(GIREPO_CFLAGS) g_ir_generate_LDADD = \ + $(top_builddir)/girepository/libgirepository-parser.la \ $(top_builddir)/girepository/libgirepository-1.0.la \ $(GIREPO_LIBS) diff --git a/tools/generate.c b/tools/generate.c index 3937f40a..cd1fedc3 100644 --- a/tools/generate.c +++ b/tools/generate.c @@ -21,1377 +21,18 @@ * Boston, MA 02111-1307, USA. */ -#include <errno.h> -#include <string.h> - #include <glib.h> -#include <glib-object.h> #include <glib/gstdio.h> +#include <gmodule.h> +#include "girwriter.h" #include "girepository.h" #include "gitypelib-internal.h" -typedef struct { - FILE *file; - GSList *stack; - gboolean show_all; -} Xml; - -typedef struct { - char *name; - guint has_children : 1; -} XmlElement; - -static XmlElement * -xml_element_new (const char *name) -{ - XmlElement *elem; - - elem = g_new (XmlElement, 1); - elem->name = g_strdup (name); - elem->has_children = FALSE; - return elem; -} - -static void -xml_element_free (XmlElement *elem) -{ - g_free (elem->name); - g_free (elem); -} - -static void -xml_printf (Xml *xml, const char *fmt, ...) -{ - va_list ap; - char *s; - - va_start (ap, fmt); - s = g_markup_vprintf_escaped (fmt, ap); - fputs (s, xml->file); - g_free (s); - va_end (ap); -} - -static void -xml_start_element (Xml *xml, const char *element_name) -{ - XmlElement *parent = NULL; - - if (xml->stack) - { - parent = xml->stack->data; - - if (!parent->has_children) - xml_printf (xml, ">\n"); - - parent->has_children = TRUE; - } - - xml_printf (xml, "%*s<%s", g_slist_length(xml->stack)*2, "", element_name); - - xml->stack = g_slist_prepend (xml->stack, xml_element_new (element_name)); -} - -static void -xml_end_element (Xml *xml, const char *name) -{ - XmlElement *elem; - - g_assert (xml->stack != NULL); - - elem = xml->stack->data; - xml->stack = g_slist_delete_link (xml->stack, xml->stack); - - if (name != NULL) - g_assert_cmpstr (name, ==, elem->name); - - if (elem->has_children) - xml_printf (xml, "%*s</%s>\n", g_slist_length (xml->stack)*2, "", elem->name); - else - xml_printf (xml, "/>\n"); - - xml_element_free (elem); -} - -static void -xml_end_element_unchecked (Xml *xml) -{ - xml_end_element (xml, NULL); -} - -static Xml * -xml_open (FILE *file) -{ - Xml *xml; - - xml = g_new (Xml, 1); - xml->file = file; - xml->stack = NULL; - - return xml; -} - -static void -xml_close (Xml *xml) -{ - g_assert (xml->stack == NULL); - if (xml->file != NULL) - { - fflush (xml->file); - if (xml->file != stdout) - fclose (xml->file); - xml->file = NULL; - } -} - -static void -xml_free (Xml *xml) -{ - xml_close (xml); - g_free (xml); -} - - -static void -check_unresolved (GIBaseInfo *info) -{ - if (g_base_info_get_type (info) != GI_INFO_TYPE_UNRESOLVED) - return; - - g_critical ("Found unresolved type '%s' '%s'\n", - g_base_info_get_name (info), g_base_info_get_namespace (info)); -} - -static void -write_type_name (const gchar *namespace, - GIBaseInfo *info, - Xml *file) -{ - if (strcmp (namespace, g_base_info_get_namespace (info)) != 0) - xml_printf (file, "%s.", g_base_info_get_namespace (info)); - - xml_printf (file, "%s", g_base_info_get_name (info)); -} - -static void -write_type_name_attribute (const gchar *namespace, - GIBaseInfo *info, - const char *attr_name, - Xml *file) -{ - xml_printf (file, " %s=\"", attr_name); - write_type_name (namespace, info, file); - xml_printf (file, "\""); -} - -static void -write_type_info (const gchar *namespace, - GITypeInfo *info, - Xml *file) -{ - gint tag; - gint i; - GITypeInfo *type; - gboolean is_pointer; - - check_unresolved ((GIBaseInfo*)info); - - tag = g_type_info_get_tag (info); - is_pointer = g_type_info_is_pointer (info); - - if (tag == GI_TYPE_TAG_VOID) - { - xml_start_element (file, "type"); - - xml_printf (file, " name=\"%s\"", is_pointer ? "any" : "none"); - - xml_end_element (file, "type"); - } - else if (G_TYPE_TAG_IS_BASIC (tag)) - { - xml_start_element (file, "type"); - xml_printf (file, " name=\"%s\"", g_type_tag_to_string (tag)); - xml_end_element (file, "type"); - } - else if (tag == GI_TYPE_TAG_ARRAY) - { - gint length, size; - char *name = NULL; - - xml_start_element (file, "array"); - - switch (g_type_info_get_array_type (info)) { - case GI_ARRAY_TYPE_C: - break; - case GI_ARRAY_TYPE_ARRAY: - name = "GLib.Array"; - break; - case GI_ARRAY_TYPE_PTR_ARRAY: - name = "GLib.PtrArray"; - break; - case GI_ARRAY_TYPE_BYTE_ARRAY: - name = "GLib.ByteArray"; - break; - default: - break; - } - - if (name) - xml_printf (file, " name=\"%s\"", name); - - type = g_type_info_get_param_type (info, 0); - - length = g_type_info_get_array_length (info); - if (length >= 0) - xml_printf (file, " length=\"%d\"", length); - - size = g_type_info_get_array_fixed_size (info); - if (size >= 0) - xml_printf (file, " fixed-size=\"%d\"", size); - - if (g_type_info_is_zero_terminated (info)) - xml_printf (file, " zero-terminated=\"1\""); - - write_type_info (namespace, type, file); - - g_base_info_unref ((GIBaseInfo *)type); - - xml_end_element (file, "array"); - } - else if (tag == GI_TYPE_TAG_INTERFACE) - { - GIBaseInfo *iface = g_type_info_get_interface (info); - xml_start_element (file, "type"); - write_type_name_attribute (namespace, iface, "name", file); - xml_end_element (file, "type"); - g_base_info_unref (iface); - } - else if (tag == GI_TYPE_TAG_GLIST) - { - xml_start_element (file, "type"); - xml_printf (file, " name=\"GLib.List\""); - type = g_type_info_get_param_type (info, 0); - if (type) - { - write_type_info (namespace, type, file); - g_base_info_unref ((GIBaseInfo *)type); - } - xml_end_element (file, "type"); - } - else if (tag == GI_TYPE_TAG_GSLIST) - { - xml_start_element (file, "type"); - xml_printf (file, " name=\"GLib.SList\""); - type = g_type_info_get_param_type (info, 0); - if (type) - { - write_type_info (namespace, type, file); - g_base_info_unref ((GIBaseInfo *)type); - } - xml_end_element (file, "type"); - } - else if (tag == GI_TYPE_TAG_GHASH) - { - xml_start_element (file, "type"); - xml_printf (file, " name=\"GLib.HashTable\""); - type = g_type_info_get_param_type (info, 0); - if (type) - { - write_type_info (namespace, type, file); - g_base_info_unref ((GIBaseInfo *)type); - type = g_type_info_get_param_type (info, 1); - write_type_info (namespace, type, file); - g_base_info_unref ((GIBaseInfo *)type); - } - xml_end_element (file, "type"); - } - else if (tag == GI_TYPE_TAG_ERROR) - { - gint n; - - xml_start_element (file, "type"); - xml_printf (file, " name=\"GLib.Error\""); - - n = g_type_info_get_n_error_domains (info); - if (n > 0) - { - for (i = 0; i < n; i++) - { - GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i); - xml_start_element (file, "type"); - write_type_name_attribute (namespace, (GIBaseInfo *)ed, "name", file); - xml_end_element (file, "type"); - g_base_info_unref ((GIBaseInfo *)ed); - } - } - - xml_end_element (file, "type"); - } - else - { - g_printerr ("Unhandled type tag %d\n", tag); - g_assert_not_reached (); - } -} - -static void -write_attributes (Xml *file, - GIBaseInfo *info) -{ - GIAttributeIter iter = { 0, }; - char *name, *value; - - while (g_base_info_iterate_attributes (info, &iter, &name, &value)) - { - xml_start_element (file, "attribute"); - xml_printf (file, " name=\"%s\" value=\"%s\"", name, value); - xml_end_element (file, "attribute"); - } -} - -static void -write_constant_value (const gchar *namespace, - GITypeInfo *info, - GArgument *argument, - Xml *file); - -static void -write_callback_info (const gchar *namespace, - GICallbackInfo *info, - Xml *file); - -static void -write_field_info (const gchar *namespace, - GIFieldInfo *info, - GIConstantInfo *branch, - Xml *file) -{ - const gchar *name; - GIFieldInfoFlags flags; - gint size; - gint offset; - GITypeInfo *type; - GIBaseInfo *interface; - GArgument value; - - name = g_base_info_get_name ((GIBaseInfo *)info); - flags = g_field_info_get_flags (info); - size = g_field_info_get_size (info); - offset = g_field_info_get_offset (info); - - xml_start_element (file, "field"); - xml_printf (file, " name=\"%s\"", name); - - /* Fields are assumed to be read-only - * (see also girwriter.py and girparser.c) - */ - if (!(flags & GI_FIELD_IS_READABLE)) - xml_printf (file, " readable=\"0\""); - if (flags & GI_FIELD_IS_WRITABLE) - xml_printf (file, " writable=\"1\""); - - if (size) - xml_printf (file, " bits=\"%d\"", size); - - write_attributes (file, (GIBaseInfo*) info); - - type = g_field_info_get_type (info); - - if (branch) - { - xml_printf (file, " branch=\""); - type = g_constant_info_get_type (branch); - g_constant_info_get_value (branch, &value); - write_constant_value (namespace, type, &value, file); - xml_printf (file, "\""); - } - - if (file->show_all) - { - if (offset >= 0) - xml_printf (file, "offset=\"%d\"", offset); - } - - interface = g_type_info_get_interface (type); - if (interface && g_base_info_get_type(interface) == GI_INFO_TYPE_CALLBACK) - write_callback_info (namespace, (GICallbackInfo *)interface, file); - else - write_type_info (namespace, type, file); - - if (interface) - g_base_info_unref (interface); - - g_base_info_unref ((GIBaseInfo *)type); - - xml_end_element (file, "field"); -} - -static void -write_callable_info (const gchar *namespace, - GICallableInfo *info, - Xml *file) -{ - GITypeInfo *type; - gint i; - - write_attributes (file, (GIBaseInfo*) info); - - type = g_callable_info_get_return_type (info); - - xml_start_element (file, "return-value"); - - switch (g_callable_info_get_caller_owns (info)) - { - case GI_TRANSFER_NOTHING: - xml_printf (file, " transfer-ownership=\"none\""); - break; - case GI_TRANSFER_CONTAINER: - xml_printf (file, " transfer-ownership=\"container\""); - break; - case GI_TRANSFER_EVERYTHING: - xml_printf (file, " transfer-ownership=\"full\""); - break; - default: - g_assert_not_reached (); - } - - if (g_callable_info_may_return_null (info)) - xml_printf (file, " allow-none=\"1\""); - - write_type_info (namespace, type, file); - - xml_end_element (file, "return-value"); - - if (g_callable_info_get_n_args (info) <= 0) - return; - - xml_start_element (file, "parameters"); - for (i = 0; i < g_callable_info_get_n_args (info); i++) - { - GIArgInfo *arg = g_callable_info_get_arg (info, i); - - xml_start_element (file, "parameter"); - xml_printf (file, " name=\"%s\"", - g_base_info_get_name ((GIBaseInfo *) arg)); - - switch (g_arg_info_get_ownership_transfer (arg)) - { - case GI_TRANSFER_NOTHING: - xml_printf (file, " transfer-ownership=\"none\""); - break; - case GI_TRANSFER_CONTAINER: - xml_printf (file, " transfer-ownership=\"container\""); - break; - case GI_TRANSFER_EVERYTHING: - xml_printf (file, " transfer-ownership=\"full\""); - break; - default: - g_assert_not_reached (); - } - - switch (g_arg_info_get_direction (arg)) - { - case GI_DIRECTION_IN: - break; - case GI_DIRECTION_OUT: - xml_printf (file, " direction=\"out\" caller-allocates=\"%s\"", - g_arg_info_is_caller_allocates (arg) ? "1" : "0"); - break; - case GI_DIRECTION_INOUT: - xml_printf (file, " direction=\"inout\""); - break; - } - - if (g_arg_info_may_be_null (arg)) - xml_printf (file, " allow-none=\"1\""); - - if (g_arg_info_is_return_value (arg)) - xml_printf (file, " retval=\"1\""); - - if (g_arg_info_is_optional (arg)) - xml_printf (file, " optional=\"1\""); - - switch (g_arg_info_get_scope (arg)) - { - case GI_SCOPE_TYPE_INVALID: - break; - case GI_SCOPE_TYPE_CALL: - xml_printf (file, " scope=\"call\""); - break; - case GI_SCOPE_TYPE_ASYNC: - xml_printf (file, " scope=\"async\""); - break; - case GI_SCOPE_TYPE_NOTIFIED: - xml_printf (file, " scope=\"notified\""); - break; - } - - if (g_arg_info_get_closure (arg) >= 0) - xml_printf (file, " closure=\"%d\"", g_arg_info_get_closure (arg)); - - if (g_arg_info_get_destroy (arg) >= 0) - xml_printf (file, " destroy=\"%d\"", g_arg_info_get_destroy (arg)); - - type = g_arg_info_get_type (arg); - write_type_info (namespace, type, file); - - xml_end_element (file, "parameter"); - - g_base_info_unref ((GIBaseInfo *)arg); - } - - xml_end_element (file, "parameters"); - g_base_info_unref ((GIBaseInfo *)type); -} - -static void -write_function_info (const gchar *namespace, - GIFunctionInfo *info, - Xml *file) -{ - GIFunctionInfoFlags flags; - const gchar *tag; - const gchar *name; - const gchar *symbol; - gboolean deprecated; - gboolean throws; - - flags = g_function_info_get_flags (info); - name = g_base_info_get_name ((GIBaseInfo *)info); - symbol = g_function_info_get_symbol (info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - throws = flags & GI_FUNCTION_THROWS; - - if (flags & GI_FUNCTION_IS_CONSTRUCTOR) - tag = "constructor"; - else if (flags & GI_FUNCTION_IS_METHOD) - tag = "method"; - else - tag = "function"; - - xml_start_element (file, tag); - xml_printf (file, " name=\"%s\" c:identifier=\"%s\"", - name, symbol); - - if (flags & GI_FUNCTION_IS_SETTER) - xml_printf (file, " type=\"setter\""); - else if (flags & GI_FUNCTION_IS_GETTER) - xml_printf (file, " type=\"getter\""); - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - if (throws) - xml_printf (file, " throws=\"1\""); - - write_callable_info (namespace, (GICallableInfo*)info, file); - xml_end_element (file, tag); -} - -static void -write_callback_info (const gchar *namespace, - GICallbackInfo *info, - Xml *file) -{ - const gchar *name; - gboolean deprecated; - - name = g_base_info_get_name ((GIBaseInfo *)info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - - xml_start_element (file, "callback"); - xml_printf (file, " name=\"%s\"", name); - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - write_callable_info (namespace, (GICallableInfo*)info, file); - xml_end_element (file, "callback"); -} - -static void -write_struct_info (const gchar *namespace, - GIStructInfo *info, - Xml *file) -{ - const gchar *name; - const gchar *type_name; - const gchar *type_init; - gboolean deprecated; - gboolean is_gtype_struct; - gboolean foreign; - gint i; - gint size; - int n_elts; - - name = g_base_info_get_name ((GIBaseInfo *)info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - - type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); - type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); - - if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED) - { - xml_start_element (file, "glib:boxed"); - xml_printf (file, " glib:name=\"%s\"", name); - } - else - { - xml_start_element (file, "record"); - xml_printf (file, " name=\"%s\"", name); - } - - if (type_name != NULL) - xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - is_gtype_struct = g_struct_info_is_gtype_struct (info); - if (is_gtype_struct) - xml_printf (file, " glib:is-gtype-struct=\"1\""); - - write_attributes (file, (GIBaseInfo*) info); - - size = g_struct_info_get_size (info); - if (file->show_all && size >= 0) - xml_printf (file, " size=\"%d\"", size); - - foreign = g_struct_info_is_foreign (info); - if (foreign) - xml_printf (file, " foreign=\"1\""); - - n_elts = g_struct_info_get_n_fields (info) + g_struct_info_get_n_methods (info); - if (n_elts > 0) - { - for (i = 0; i < g_struct_info_get_n_fields (info); i++) - { - GIFieldInfo *field = g_struct_info_get_field (info, i); - write_field_info (namespace, field, NULL, file); - g_base_info_unref ((GIBaseInfo *)field); - } - - for (i = 0; i < g_struct_info_get_n_methods (info); i++) - { - GIFunctionInfo *function = g_struct_info_get_method (info, i); - write_function_info (namespace, function, file); - g_base_info_unref ((GIBaseInfo *)function); - } - - } - - xml_end_element_unchecked (file); -} - -static void -write_value_info (const gchar *namespace, - GIValueInfo *info, - Xml *file) -{ - const gchar *name; - glong value; - gboolean deprecated; - - name = g_base_info_get_name ((GIBaseInfo *)info); - value = g_value_info_get_value (info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - - xml_start_element (file, "member"); - xml_printf (file, " name=\"%s\" value=\"%ld\"", name, value); - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - write_attributes (file, (GIBaseInfo*) info); - - xml_end_element (file, "member"); -} - -static void -write_constant_value (const gchar *namespace, - GITypeInfo *type, - GArgument *value, - Xml *file) -{ - switch (g_type_info_get_tag (type)) - { - case GI_TYPE_TAG_BOOLEAN: - xml_printf (file, "%d", value->v_boolean); - break; - case GI_TYPE_TAG_INT8: - xml_printf (file, "%d", value->v_int8); - break; - case GI_TYPE_TAG_UINT8: - xml_printf (file, "%d", value->v_uint8); - break; - case GI_TYPE_TAG_INT16: - xml_printf (file, "%" G_GINT16_FORMAT, value->v_int16); - break; - case GI_TYPE_TAG_UINT16: - xml_printf (file, "%" G_GUINT16_FORMAT, value->v_uint16); - break; - case GI_TYPE_TAG_INT32: - xml_printf (file, "%" G_GINT32_FORMAT, value->v_int32); - break; - case GI_TYPE_TAG_UINT32: - xml_printf (file, "%" G_GUINT32_FORMAT, value->v_uint32); - break; - case GI_TYPE_TAG_INT64: - xml_printf (file, "%" G_GINT64_FORMAT, value->v_int64); - break; - case GI_TYPE_TAG_UINT64: - xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64); - break; - case GI_TYPE_TAG_INT: - xml_printf (file, "%d", value->v_int); - break; - case GI_TYPE_TAG_UINT: - xml_printf (file, "%d", value->v_uint); - break; - case GI_TYPE_TAG_LONG: - xml_printf (file, "%ld", value->v_long); - break; - case GI_TYPE_TAG_ULONG: - xml_printf (file, "%ld", value->v_ulong); - break; - case GI_TYPE_TAG_SSIZE: - xml_printf (file, "%zd", value->v_ssize); - break; - case GI_TYPE_TAG_SIZE: - xml_printf (file, "%zd", value->v_size); - break; - case GI_TYPE_TAG_FLOAT: - xml_printf (file, "%f", value->v_float); - break; - case GI_TYPE_TAG_DOUBLE: - xml_printf (file, "%f", value->v_double); - break; - case GI_TYPE_TAG_UTF8: - case GI_TYPE_TAG_FILENAME: - xml_printf (file, "%s", value->v_string); - break; - default: - g_assert_not_reached (); - } -} - -static void -write_constant_info (const gchar *namespace, - GIConstantInfo *info, - Xml *file) -{ - GITypeInfo *type; - const gchar *name; - gboolean deprecated; - GArgument value; - - name = g_base_info_get_name ((GIBaseInfo *)info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - - xml_start_element (file, "constant"); - xml_printf (file, " name=\"%s\"", name); - - type = g_constant_info_get_type (info); - xml_printf (file, " value=\""); - - g_constant_info_get_value (info, &value); - write_constant_value (namespace, type, &value, file); - xml_printf (file, "\""); - - write_type_info (namespace, type, file); - - write_attributes (file, (GIBaseInfo*) info); - - xml_end_element (file, "constant"); - - g_base_info_unref ((GIBaseInfo *)type); -} - - -static void -write_enum_info (const gchar *namespace, - GIEnumInfo *info, - Xml *file) -{ - const gchar *name; - const gchar *type_name; - const gchar *type_init; - gboolean deprecated; - gint i; - - name = g_base_info_get_name ((GIBaseInfo *)info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - - type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); - type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); - - if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM) - xml_start_element (file, "enumeration"); - else - xml_start_element (file, "bitfield"); - xml_printf (file, " name=\"%s\"", name); - - if (type_init) - xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - write_attributes (file, (GIBaseInfo*) info); - - for (i = 0; i < g_enum_info_get_n_values (info); i++) - { - GIValueInfo *value = g_enum_info_get_value (info, i); - write_value_info (namespace, value, file); - g_base_info_unref ((GIBaseInfo *)value); - } - - xml_end_element_unchecked (file); -} - -static void -write_signal_info (const gchar *namespace, - GISignalInfo *info, - Xml *file) -{ - GSignalFlags flags; - const gchar *name; - gboolean deprecated; - - name = g_base_info_get_name ((GIBaseInfo *)info); - flags = g_signal_info_get_flags (info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - - xml_start_element (file, "glib:signal"); - xml_printf (file, " name=\"%s\"", name); - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - if (flags & G_SIGNAL_RUN_FIRST) - xml_printf (file, " when=\"FIRST\""); - else if (flags & G_SIGNAL_RUN_LAST) - xml_printf (file, " when=\"LAST\""); - else if (flags & G_SIGNAL_RUN_CLEANUP) - xml_printf (file, " when=\"CLEANUP\""); - - if (flags & G_SIGNAL_NO_RECURSE) - xml_printf (file, " no-recurse=\"1\""); - - if (flags & G_SIGNAL_DETAILED) - xml_printf (file, " detailed=\"1\""); - - if (flags & G_SIGNAL_ACTION) - xml_printf (file, " action=\"1\""); - - if (flags & G_SIGNAL_NO_HOOKS) - xml_printf (file, " no-hooks=\"1\""); - - write_callable_info (namespace, (GICallableInfo*)info, file); - - xml_end_element (file, "glib:signal"); -} - -static void -write_vfunc_info (const gchar *namespace, - GIVFuncInfo *info, - Xml *file) -{ - GIVFuncInfoFlags flags; - const gchar *name; - GIFunctionInfo *invoker; - gboolean deprecated; - gint offset; - - name = g_base_info_get_name ((GIBaseInfo *)info); - flags = g_vfunc_info_get_flags (info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - offset = g_vfunc_info_get_offset (info); - invoker = g_vfunc_info_get_invoker (info); - - xml_start_element (file, "virtual-method"); - xml_printf (file, " name=\"%s\"", name); - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - if (flags & GI_VFUNC_MUST_CHAIN_UP) - xml_printf (file, " must-chain-up=\"1\""); - - if (flags & GI_VFUNC_MUST_OVERRIDE) - xml_printf (file, " override=\"always\""); - else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE) - xml_printf (file, " override=\"never\""); - - xml_printf (file, " offset=\"%d\"", offset); - - if (invoker) - xml_printf (file, " invoker=\"%s\"", g_base_info_get_name ((GIBaseInfo*)invoker)); - - write_callable_info (namespace, (GICallableInfo*)info, file); - - xml_end_element (file, "virtual-method"); -} - -static void -write_property_info (const gchar *namespace, - GIPropertyInfo *info, - Xml *file) -{ - GParamFlags flags; - const gchar *name; - gboolean deprecated; - GITypeInfo *type; - - name = g_base_info_get_name ((GIBaseInfo *)info); - flags = g_property_info_get_flags (info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - - xml_start_element (file, "property"); - xml_printf (file, " name=\"%s\"", name); - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - /* Properties are assumed to be read-only (see also girwriter.py) */ - if (!(flags & G_PARAM_READABLE)) - xml_printf (file, " readable=\"0\""); - if (flags & G_PARAM_WRITABLE) - xml_printf (file, " writable=\"1\""); - - if (flags & G_PARAM_CONSTRUCT) - xml_printf (file, " construct=\"1\""); - - if (flags & G_PARAM_CONSTRUCT_ONLY) - xml_printf (file, " construct-only=\"1\""); - - write_attributes (file, (GIBaseInfo*) info); - - type = g_property_info_get_type (info); - - write_type_info (namespace, type, file); - - xml_end_element (file, "property"); -} - -static void -write_object_info (const gchar *namespace, - GIObjectInfo *info, - Xml *file) -{ - const gchar *name; - const gchar *type_name; - const gchar *type_init; - gboolean deprecated; - gboolean is_abstract; - GIObjectInfo *pnode; - GIStructInfo *class_struct; - gint i; - - name = g_base_info_get_name ((GIBaseInfo *)info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - is_abstract = g_object_info_get_abstract (info); - - type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); - type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); - xml_start_element (file, "class"); - xml_printf (file, " name=\"%s\"", name); - - pnode = g_object_info_get_parent (info); - if (pnode) - { - write_type_name_attribute (namespace, (GIBaseInfo *)pnode, "parent", file); - g_base_info_unref ((GIBaseInfo *)pnode); - } - - class_struct = g_object_info_get_class_struct (info); - if (class_struct) - { - write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file); - g_base_info_unref ((GIBaseInfo*)class_struct); - } - - if (is_abstract) - xml_printf (file, " abstract=\"1\""); - - xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - write_attributes (file, (GIBaseInfo*) info); - - if (g_object_info_get_n_interfaces (info) > 0) - { - for (i = 0; i < g_object_info_get_n_interfaces (info); i++) - { - GIInterfaceInfo *imp = g_object_info_get_interface (info, i); - xml_start_element (file, "implements"); - write_type_name_attribute (namespace, (GIBaseInfo *)imp, "name", file); - xml_end_element (file, "implements"); - g_base_info_unref ((GIBaseInfo*)imp); - } - } - - for (i = 0; i < g_object_info_get_n_fields (info); i++) - { - GIFieldInfo *field = g_object_info_get_field (info, i); - write_field_info (namespace, field, NULL, file); - g_base_info_unref ((GIBaseInfo *)field); - } - - for (i = 0; i < g_object_info_get_n_methods (info); i++) - { - GIFunctionInfo *function = g_object_info_get_method (info, i); - write_function_info (namespace, function, file); - g_base_info_unref ((GIBaseInfo *)function); - } - - for (i = 0; i < g_object_info_get_n_properties (info); i++) - { - GIPropertyInfo *prop = g_object_info_get_property (info, i); - write_property_info (namespace, prop, file); - g_base_info_unref ((GIBaseInfo *)prop); - } - - for (i = 0; i < g_object_info_get_n_signals (info); i++) - { - GISignalInfo *signal = g_object_info_get_signal (info, i); - write_signal_info (namespace, signal, file); - g_base_info_unref ((GIBaseInfo *)signal); - } - - for (i = 0; i < g_object_info_get_n_vfuncs (info); i++) - { - GIVFuncInfo *vfunc = g_object_info_get_vfunc (info, i); - write_vfunc_info (namespace, vfunc, file); - g_base_info_unref ((GIBaseInfo *)vfunc); - } - - for (i = 0; i < g_object_info_get_n_constants (info); i++) - { - GIConstantInfo *constant = g_object_info_get_constant (info, i); - write_constant_info (namespace, constant, file); - g_base_info_unref ((GIBaseInfo *)constant); - } - - xml_end_element (file, "class"); -} - -static void -write_interface_info (const gchar *namespace, - GIInterfaceInfo *info, - Xml *file) -{ - const gchar *name; - const gchar *type_name; - const gchar *type_init; - GIStructInfo *class_struct; - gboolean deprecated; - gint i; - - name = g_base_info_get_name ((GIBaseInfo *)info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - - type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); - type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); - xml_start_element (file, "interface"); - xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"", - name, type_name, type_init); - - class_struct = g_interface_info_get_iface_struct (info); - if (class_struct) - { - write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file); - g_base_info_unref ((GIBaseInfo*)class_struct); - } - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - write_attributes (file, (GIBaseInfo*) info); - - if (g_interface_info_get_n_prerequisites (info) > 0) - { - for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++) - { - GIBaseInfo *req = g_interface_info_get_prerequisite (info, i); - - xml_start_element (file, "prerequisite"); - write_type_name_attribute (namespace, req, "name", file); - - xml_end_element_unchecked (file); - g_base_info_unref (req); - } - } - - for (i = 0; i < g_interface_info_get_n_methods (info); i++) - { - GIFunctionInfo *function = g_interface_info_get_method (info, i); - write_function_info (namespace, function, file); - g_base_info_unref ((GIBaseInfo *)function); - } - - for (i = 0; i < g_interface_info_get_n_properties (info); i++) - { - GIPropertyInfo *prop = g_interface_info_get_property (info, i); - write_property_info (namespace, prop, file); - g_base_info_unref ((GIBaseInfo *)prop); - } - - for (i = 0; i < g_interface_info_get_n_signals (info); i++) - { - GISignalInfo *signal = g_interface_info_get_signal (info, i); - write_signal_info (namespace, signal, file); - g_base_info_unref ((GIBaseInfo *)signal); - } - - for (i = 0; i < g_interface_info_get_n_vfuncs (info); i++) - { - GIVFuncInfo *vfunc = g_interface_info_get_vfunc (info, i); - write_vfunc_info (namespace, vfunc, file); - g_base_info_unref ((GIBaseInfo *)vfunc); - } - - for (i = 0; i < g_interface_info_get_n_constants (info); i++) - { - GIConstantInfo *constant = g_interface_info_get_constant (info, i); - write_constant_info (namespace, constant, file); - g_base_info_unref ((GIBaseInfo *)constant); - } - - xml_end_element (file, "interface"); -} - -static void -write_error_domain_info (const gchar *namespace, - GIErrorDomainInfo *info, - Xml *file) -{ - GIBaseInfo *enum_; - const gchar *name, *quark; - - name = g_base_info_get_name ((GIBaseInfo *)info); - quark = g_error_domain_info_get_quark (info); - enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info); - xml_start_element (file, "errordomain"); - xml_printf (file, " name=\"%s\" get-quark=\"%s\"", - name, quark); - write_type_name_attribute (namespace, enum_, "codes", file); - xml_end_element (file, "errordomain"); - g_base_info_unref (enum_); -} - -static void -write_union_info (const gchar *namespace, - GIUnionInfo *info, - Xml *file) -{ - const gchar *name; - const gchar *type_name; - const gchar *type_init; - gboolean deprecated; - gint i; - gint size; - - name = g_base_info_get_name ((GIBaseInfo *)info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - - type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); - type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); - - xml_start_element (file, "union"); - xml_printf (file, " name=\"%s\"", name); - - if (type_name) - xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init); - - if (deprecated) - xml_printf (file, " deprecated=\"1\""); - - size = g_union_info_get_size (info); - if (file->show_all && size >= 0) - xml_printf (file, " size=\"%d\"", size); - - write_attributes (file, (GIBaseInfo*) info); - - if (g_union_info_is_discriminated (info)) - { - gint offset; - GITypeInfo *type; - - offset = g_union_info_get_discriminator_offset (info); - type = g_union_info_get_discriminator_type (info); - - xml_start_element (file, "discriminator"); - xml_printf (file, " offset=\"%d\" type=\"", offset); - write_type_info (namespace, type, file); - xml_end_element (file, "discriminator"); - g_base_info_unref ((GIBaseInfo *)type); - } - - for (i = 0; i < g_union_info_get_n_fields (info); i++) - { - GIFieldInfo *field = g_union_info_get_field (info, i); - GIConstantInfo *constant = g_union_info_get_discriminator (info, i); - write_field_info (namespace, field, constant, file); - g_base_info_unref ((GIBaseInfo *)field); - if (constant) - g_base_info_unref ((GIBaseInfo *)constant); - } - - for (i = 0; i < g_union_info_get_n_methods (info); i++) - { - GIFunctionInfo *function = g_union_info_get_method (info, i); - write_function_info (namespace, function, file); - g_base_info_unref ((GIBaseInfo *)function); - } - - xml_end_element (file, "union"); -} - -static void -write_repository (const char *filename, - const char *namespace, - gboolean needs_prefix, - gboolean show_all) -{ - FILE *ofile; - gint i, j; - char **dependencies; - GIRepository *repository; - Xml *xml; - - repository = g_irepository_get_default (); - - if (filename == NULL) - ofile = stdout; - else - { - gchar *full_filename; - - if (needs_prefix) - full_filename = g_strdup_printf ("%s-%s", namespace, filename); - else - full_filename = g_strdup (filename); - ofile = g_fopen (filename, "w"); - - if (ofile == NULL) - { - g_fprintf (stderr, "failed to open '%s': %s\n", - full_filename, g_strerror (errno)); - g_free (full_filename); - - return; - } - - g_free (full_filename); - } - - xml = xml_open (ofile); - xml->show_all = show_all; - xml_printf (xml, "<?xml version=\"1.0\"?>\n"); - xml_start_element (xml, "repository"); - xml_printf (xml, " version=\"1.0\"\n" - " xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n" - " xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n" - " xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\""); - - dependencies = g_irepository_get_dependencies (repository, - namespace); - if (dependencies != NULL) - { - for (i = 0; dependencies[i]; i++) - { - char **parts = g_strsplit (dependencies[i], "-", 2); - xml_start_element (xml, "include"); - xml_printf (xml, " name=\"%s\" version=\"%s\"", parts[0], parts[1]); - xml_end_element (xml, "include"); - g_strfreev (parts); - } - } - - if (TRUE) - { - const gchar *shared_library; - const gchar *c_prefix; - const char *ns = namespace; - const char *version; - - version = g_irepository_get_version (repository, ns); - - shared_library = g_irepository_get_shared_library (repository, ns); - c_prefix = g_irepository_get_c_prefix (repository, ns); - xml_start_element (xml, "namespace"); - xml_printf (xml, " name=\"%s\" version=\"%s\"", ns, version); - if (shared_library) - xml_printf (xml, " shared-library=\"%s\"", shared_library); - if (c_prefix) - xml_printf (xml, " c:prefix=\"%s\"", c_prefix); - - for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++) - { - GIBaseInfo *info = g_irepository_get_info (repository, ns, j); - switch (g_base_info_get_type (info)) - { - case GI_INFO_TYPE_FUNCTION: - write_function_info (ns, (GIFunctionInfo *)info, xml); - break; - - case GI_INFO_TYPE_CALLBACK: - write_callback_info (ns, (GICallbackInfo *)info, xml); - break; - - case GI_INFO_TYPE_STRUCT: - case GI_INFO_TYPE_BOXED: - write_struct_info (ns, (GIStructInfo *)info, xml); - break; - - case GI_INFO_TYPE_UNION: - write_union_info (ns, (GIUnionInfo *)info, xml); - break; - - case GI_INFO_TYPE_ENUM: - case GI_INFO_TYPE_FLAGS: - write_enum_info (ns, (GIEnumInfo *)info, xml); - break; - - case GI_INFO_TYPE_CONSTANT: - write_constant_info (ns, (GIConstantInfo *)info, xml); - break; - - case GI_INFO_TYPE_OBJECT: - write_object_info (ns, (GIObjectInfo *)info, xml); - break; - - case GI_INFO_TYPE_INTERFACE: - write_interface_info (ns, (GIInterfaceInfo *)info, xml); - break; - - case GI_INFO_TYPE_ERROR_DOMAIN: - write_error_domain_info (ns, (GIErrorDomainInfo *)info, xml); - break; - - default: - g_error ("unknown info type %d\n", g_base_info_get_type (info)); - } - - g_base_info_unref (info); - } - - xml_end_element (xml, "namespace"); - } - - xml_end_element (xml, "repository"); - - xml_free (xml); -} - static const guchar * load_typelib (const gchar *filename, - GModule **dlhandle, - gsize *len) + GModule **dlhandle, + gsize *len) { guchar *typelib; gsize *typelib_size; @@ -1521,7 +162,7 @@ main (int argc, char *argv[]) return 1; } - write_repository (output, namespace, needs_prefix, show_all); + gir_writer_write (output, namespace, needs_prefix, show_all); if (dlhandle) { |