mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-10-31 03:26:19 +01:00
b6d50e2951
This patch adds support for instantiable fundamental object types, which are not GObject based. This is mostly interesting for being able to support GstMiniObject's which are extensivly used in GStreamer. Includes a big test case to the Everything module (inspired by GstMiniObject) which should be used by language bindings who wishes to test this functionallity. This patch increases the size of the typelib and breaks compatibility with older typelibs. https://bugzilla.gnome.org/show_bug.cgi?id=568913
1439 lines
38 KiB
C
1439 lines
38 KiB
C
/* -*- 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_slice_new (XmlElement);
|
|
elem->name = g_strdup (name);
|
|
elem->has_children = FALSE;
|
|
return elem;
|
|
}
|
|
|
|
static void
|
|
xml_element_free (XmlElement *elem)
|
|
{
|
|
g_free (elem->name);
|
|
g_slice_free (XmlElement, 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_slice_new (Xml);
|
|
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_slice_free (Xml, 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_ownership_transfer (GITransfer transfer,
|
|
Xml *file)
|
|
{
|
|
switch (transfer)
|
|
{
|
|
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 ();
|
|
}
|
|
}
|
|
|
|
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_return_value_attributes (Xml *file,
|
|
GICallableInfo *info)
|
|
{
|
|
GIAttributeIter iter = { 0, };
|
|
char *name, *value;
|
|
|
|
while (g_callable_info_iterate_return_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");
|
|
|
|
write_ownership_transfer (g_callable_info_get_caller_owns (info), file);
|
|
|
|
if (g_callable_info_may_return_null (info))
|
|
xml_printf (file, " allow-none=\"1\"");
|
|
|
|
write_return_value_attributes (file, info);
|
|
|
|
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));
|
|
|
|
write_ownership_transfer (g_arg_info_get_ownership_transfer (arg), file);
|
|
|
|
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));
|
|
|
|
write_attributes (file, (GIBaseInfo*) 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_ownership_transfer (g_property_info_get_ownership_transfer (info), file);
|
|
|
|
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;
|
|
const gchar *func;
|
|
gboolean deprecated;
|
|
gboolean is_abstract;
|
|
gboolean is_fundamental;
|
|
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);
|
|
is_fundamental = g_object_info_get_fundamental (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 (is_fundamental)
|
|
xml_printf (file, " glib:fundamental=\"1\"");
|
|
|
|
func = g_object_info_get_unref_function (info);
|
|
if (func)
|
|
xml_printf (file, " glib:unref-function=\"%s\"", func);
|
|
|
|
func = g_object_info_get_ref_function (info);
|
|
if (func)
|
|
xml_printf (file, " glib:ref-function=\"%s\"", func);
|
|
|
|
func = g_object_info_get_set_value_function (info);
|
|
if (func)
|
|
xml_printf (file, " glib:set-value-function=\"%s\"", func);
|
|
|
|
func = g_object_info_get_get_value_function (info);
|
|
if (func)
|
|
xml_printf (file, " glib:get-value-function=\"%s\"", func);
|
|
|
|
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: if the filename needs prefixing
|
|
* @show_all: if field size calculations should be included
|
|
*
|
|
* 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);
|
|
}
|