(root)/
glib-2.79.0/
girepository/
girwriter.c
       1  /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
       2   * GObject introspection: IDL generator
       3   *
       4   * Copyright (C) 2005 Matthias Clasen
       5   * Copyright (C) 2008,2009 Red Hat, Inc.
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   *
       9   * This library is free software; you can redistribute it and/or
      10   * modify it under the terms of the GNU Lesser General Public
      11   * License as published by the Free Software Foundation; either
      12   * version 2 of the License, or (at your option) any later version.
      13   *
      14   * This library is distributed in the hope that it will be useful,
      15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17   * Lesser General Public License for more details.
      18   *
      19   * You should have received a copy of the GNU Lesser General Public
      20   * License along with this library; if not, write to the
      21   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      22   * Boston, MA 02111-1307, USA.
      23   */
      24  
      25  #include "config.h"
      26  
      27  #include "girwriter-private.h"
      28  
      29  #include "girepository.h"
      30  #include "gitypelib-internal.h"
      31  
      32  #include <errno.h>
      33  #include <string.h>
      34  #include <stdio.h>
      35  
      36  #include <glib.h>
      37  #include <glib-object.h>
      38  #include <glib/gstdio.h>
      39  
      40  typedef struct {
      41    FILE *file;
      42    GSList *stack;
      43    gboolean show_all;
      44  } Xml;
      45  
      46  typedef struct {
      47    char *name;
      48    guint has_children : 1;
      49  } XmlElement;
      50  
      51  static XmlElement *
      52  xml_element_new (const char *name)
      53  {
      54    XmlElement *elem;
      55  
      56    elem = g_slice_new (XmlElement);
      57    elem->name = g_strdup (name);
      58    elem->has_children = FALSE;
      59    return elem;
      60  }
      61  
      62  static void
      63  xml_element_free (XmlElement *elem)
      64  {
      65    g_free (elem->name);
      66    g_slice_free (XmlElement, elem);
      67  }
      68  
      69  static void
      70  xml_printf (Xml *xml, const char *fmt, ...) G_GNUC_PRINTF (2, 3);
      71  
      72  static void
      73  xml_printf (Xml *xml, const char *fmt, ...)
      74  {
      75    va_list ap;
      76    char *s;
      77  
      78    va_start (ap, fmt);
      79    s = g_markup_vprintf_escaped (fmt, ap);
      80    fputs (s, xml->file);
      81    g_free (s);
      82    va_end (ap);
      83  }
      84  
      85  static void
      86  xml_start_element (Xml *xml, const char *element_name)
      87  {
      88    XmlElement *parent = NULL;
      89  
      90    if (xml->stack)
      91      {
      92        parent = xml->stack->data;
      93  
      94        if (!parent->has_children)
      95          xml_printf (xml, ">\n");
      96  
      97        parent->has_children = TRUE;
      98      }
      99  
     100    xml_printf (xml, "%*s<%s", g_slist_length(xml->stack)*2, "", element_name);
     101  
     102    xml->stack = g_slist_prepend (xml->stack, xml_element_new (element_name));
     103  }
     104  
     105  static void
     106  xml_end_element (Xml *xml, const char *name)
     107  {
     108    XmlElement *elem;
     109  
     110    g_assert (xml->stack != NULL);
     111  
     112    elem = xml->stack->data;
     113    xml->stack = g_slist_delete_link (xml->stack, xml->stack);
     114  
     115    if (name != NULL)
     116      g_assert_cmpstr (name, ==, elem->name);
     117  
     118    if (elem->has_children)
     119      xml_printf (xml, "%*s</%s>\n", g_slist_length (xml->stack)*2, "", elem->name);
     120    else
     121      xml_printf (xml, "/>\n");
     122  
     123    xml_element_free (elem);
     124  }
     125  
     126  static void
     127  xml_end_element_unchecked (Xml *xml)
     128  {
     129    xml_end_element (xml, NULL);
     130  }
     131  
     132  static Xml *
     133  xml_open (FILE *file)
     134  {
     135    Xml *xml;
     136  
     137    xml = g_slice_new (Xml);
     138    xml->file = file;
     139    xml->stack = NULL;
     140  
     141    return xml;
     142  }
     143  
     144  static void
     145  xml_close (Xml *xml)
     146  {
     147    g_assert (xml->stack == NULL);
     148    if (xml->file != NULL)
     149      {
     150        fflush (xml->file);
     151        if (xml->file != stdout)
     152          fclose (xml->file);
     153        xml->file = NULL;
     154      }
     155  }
     156  
     157  static void
     158  xml_free (Xml *xml)
     159  {
     160    xml_close (xml);
     161    g_slice_free (Xml, xml);
     162  }
     163  
     164  
     165  static void
     166  check_unresolved (GIBaseInfo *info)
     167  {
     168    if (gi_base_info_get_info_type (info) != GI_INFO_TYPE_UNRESOLVED)
     169      return;
     170  
     171    g_critical ("Found unresolved type '%s' '%s'\n",
     172  	      gi_base_info_get_name (info), gi_base_info_get_namespace (info));
     173  }
     174  
     175  static void
     176  write_type_name (const gchar *ns,
     177  		 GIBaseInfo  *info,
     178  		 Xml         *file)
     179  {
     180    if (strcmp (ns, gi_base_info_get_namespace (info)) != 0)
     181      xml_printf (file, "%s.", gi_base_info_get_namespace (info));
     182  
     183    xml_printf (file, "%s", gi_base_info_get_name (info));
     184  }
     185  
     186  static void
     187  write_type_name_attribute (const gchar *ns,
     188  			   GIBaseInfo  *info,
     189  			   const char  *attr_name,
     190  			   Xml         *file)
     191  {
     192    xml_printf (file, " %s=\"", attr_name);
     193    write_type_name (ns, info, file);
     194    xml_printf (file, "\"");
     195  }
     196  
     197   static void
     198  write_ownership_transfer (GITransfer transfer,
     199                            Xml       *file)
     200  {
     201    switch (transfer)
     202      {
     203      case GI_TRANSFER_NOTHING:
     204        xml_printf (file, " transfer-ownership=\"none\"");
     205        break;
     206      case GI_TRANSFER_CONTAINER:
     207        xml_printf (file, " transfer-ownership=\"container\"");
     208        break;
     209      case GI_TRANSFER_EVERYTHING:
     210        xml_printf (file, " transfer-ownership=\"full\"");
     211        break;
     212      default:
     213        g_assert_not_reached ();
     214      }
     215  }
     216  
     217  static void
     218  write_type_info (const gchar *ns,
     219  		 GITypeInfo  *info,
     220  		 Xml         *file)
     221  {
     222    gint tag;
     223    GITypeInfo *type;
     224    gboolean is_pointer;
     225  
     226    check_unresolved ((GIBaseInfo*)info);
     227  
     228    tag = gi_type_info_get_tag (info);
     229    is_pointer = gi_type_info_is_pointer (info);
     230  
     231    if (tag == GI_TYPE_TAG_VOID)
     232      {
     233        xml_start_element (file, "type");
     234  
     235        xml_printf (file, " name=\"%s\"", is_pointer ? "any" : "none");
     236  
     237        xml_end_element (file, "type");
     238      }
     239    else if (GI_TYPE_TAG_IS_BASIC (tag))
     240      {
     241        xml_start_element (file, "type");
     242        xml_printf (file, " name=\"%s\"", gi_type_tag_to_string (tag));
     243        xml_end_element (file, "type");
     244      }
     245    else if (tag == GI_TYPE_TAG_ARRAY)
     246      {
     247        gint length;
     248        gssize size;
     249        const char *name = NULL;
     250  
     251        xml_start_element (file, "array");
     252  
     253        switch (gi_type_info_get_array_type (info)) {
     254          case GI_ARRAY_TYPE_C:
     255              break;
     256          case GI_ARRAY_TYPE_ARRAY:
     257              name = "GLib.Array";
     258              break;
     259          case GI_ARRAY_TYPE_PTR_ARRAY:
     260              name = "GLib.PtrArray";
     261              break;
     262          case GI_ARRAY_TYPE_BYTE_ARRAY:
     263              name = "GLib.ByteArray";
     264              break;
     265          default:
     266              break;
     267        }
     268  
     269        if (name)
     270          xml_printf (file, " name=\"%s\"", name);
     271  
     272        type = gi_type_info_get_param_type (info, 0);
     273  
     274        length = gi_type_info_get_array_length_index (info);
     275        if (length >= 0)
     276          xml_printf (file, " length=\"%d\"", length);
     277  
     278        size = gi_type_info_get_array_fixed_size (info);
     279        if (size >= 0)
     280          xml_printf (file, " fixed-size=\"%" G_GSSIZE_FORMAT "\"", size);
     281  
     282        if (gi_type_info_is_zero_terminated (info))
     283  	xml_printf (file, " zero-terminated=\"1\"");
     284  
     285        write_type_info (ns, type, file);
     286  
     287        gi_base_info_unref ((GIBaseInfo *)type);
     288  
     289        xml_end_element (file, "array");
     290      }
     291    else if (tag == GI_TYPE_TAG_INTERFACE)
     292      {
     293        GIBaseInfo *iface = gi_type_info_get_interface (info);
     294        xml_start_element (file, "type");
     295        write_type_name_attribute (ns, iface, "name", file);
     296        xml_end_element (file, "type");
     297        gi_base_info_unref (iface);
     298      }
     299    else if (tag == GI_TYPE_TAG_GLIST)
     300      {
     301        xml_start_element (file, "type");
     302        xml_printf (file, " name=\"GLib.List\"");
     303        type = gi_type_info_get_param_type (info, 0);
     304        if (type)
     305  	{
     306  	  write_type_info (ns, type, file);
     307  	  gi_base_info_unref ((GIBaseInfo *)type);
     308  	}
     309        xml_end_element (file, "type");
     310      }
     311    else if (tag == GI_TYPE_TAG_GSLIST)
     312      {
     313        xml_start_element (file, "type");
     314        xml_printf (file, " name=\"GLib.SList\"");
     315        type = gi_type_info_get_param_type (info, 0);
     316        if (type)
     317  	{
     318  	  write_type_info (ns, type, file);
     319  	  gi_base_info_unref ((GIBaseInfo *)type);
     320  	}
     321        xml_end_element (file, "type");
     322      }
     323    else if (tag == GI_TYPE_TAG_GHASH)
     324      {
     325        xml_start_element (file, "type");
     326        xml_printf (file, " name=\"GLib.HashTable\"");
     327        type = gi_type_info_get_param_type (info, 0);
     328        if (type)
     329  	{
     330  	  write_type_info (ns, type, file);
     331  	  gi_base_info_unref ((GIBaseInfo *)type);
     332  	  type = gi_type_info_get_param_type (info, 1);
     333  	  write_type_info (ns, type, file);
     334  	  gi_base_info_unref ((GIBaseInfo *)type);
     335  	}
     336        xml_end_element (file, "type");
     337      }
     338    else if (tag == GI_TYPE_TAG_ERROR)
     339      {
     340        xml_start_element (file, "type");
     341        xml_printf (file, " name=\"GLib.Error\"");
     342        xml_end_element (file, "type");
     343      }
     344    else
     345      {
     346        g_printerr ("Unhandled type tag %d\n", tag);
     347        g_assert_not_reached ();
     348      }
     349  }
     350  
     351  static void
     352  write_attributes (Xml *file,
     353                    GIBaseInfo *info)
     354  {
     355    GIAttributeIter iter = { 0, };
     356    const char *name, *value;
     357  
     358    while (gi_base_info_iterate_attributes (info, &iter, &name, &value))
     359      {
     360        xml_start_element (file, "attribute");
     361        xml_printf (file, " name=\"%s\" value=\"%s\"", name, value);
     362        xml_end_element (file, "attribute");
     363      }
     364  }
     365  
     366  static void
     367  write_return_value_attributes (Xml *file,
     368                                 GICallableInfo *info)
     369  {
     370    GIAttributeIter iter = { 0, };
     371    const char *name, *value;
     372  
     373    while (gi_callable_info_iterate_return_attributes (info, &iter, &name, &value))
     374      {
     375        xml_start_element (file, "attribute");
     376        xml_printf (file, " name=\"%s\" value=\"%s\"", name, value);
     377        xml_end_element (file, "attribute");
     378      }
     379  }
     380  
     381  static void
     382  write_constant_value (const gchar *ns,
     383  		      GITypeInfo *info,
     384  		      GIArgument *argument,
     385  		      Xml *file);
     386  
     387  static void
     388  write_callback_info (const gchar    *ns,
     389  		     GICallbackInfo *info,
     390  		     Xml            *file);
     391  
     392  static void
     393  write_field_info (const gchar *ns,
     394  		  GIFieldInfo *info,
     395  		  GIConstantInfo *branch,
     396  		  Xml         *file)
     397  {
     398    const gchar *name;
     399    GIFieldInfoFlags flags;
     400    gint size;
     401    gint offset;
     402    GITypeInfo *type;
     403    GIBaseInfo *interface;
     404    GIArgument value;
     405  
     406    name = gi_base_info_get_name ((GIBaseInfo *)info);
     407    flags = gi_field_info_get_flags (info);
     408    size = gi_field_info_get_size (info);
     409    offset = gi_field_info_get_offset (info);
     410  
     411    xml_start_element (file, "field");
     412    xml_printf (file, " name=\"%s\"", name);
     413  
     414    /* Fields are assumed to be read-only
     415     * (see also girwriter.py and girparser.c)
     416     */
     417    if (!(flags & GI_FIELD_IS_READABLE))
     418      xml_printf (file, " readable=\"0\"");
     419    if (flags & GI_FIELD_IS_WRITABLE)
     420      xml_printf (file, " writable=\"1\"");
     421  
     422    if (size)
     423      xml_printf (file, " bits=\"%d\"", size);
     424  
     425    write_attributes (file, (GIBaseInfo*) info);
     426  
     427    type = gi_field_info_get_type_info (info);
     428  
     429    if (branch)
     430      {
     431        xml_printf (file, " branch=\"");
     432        gi_base_info_unref ((GIBaseInfo *)type);
     433        type = gi_constant_info_get_type_info (branch);
     434        gi_constant_info_get_value (branch, &value);
     435        write_constant_value (ns, type, &value, file);
     436        xml_printf (file, "\"");
     437      }
     438  
     439    if (file->show_all)
     440      {
     441        if (offset >= 0)
     442          xml_printf (file, "offset=\"%d\"", offset);
     443      }
     444  
     445    interface = gi_type_info_get_interface (type);
     446    if (interface && gi_base_info_get_info_type (interface) == GI_INFO_TYPE_CALLBACK)
     447      write_callback_info (ns, (GICallbackInfo *)interface, file);
     448    else
     449      write_type_info (ns, type, file);
     450  
     451    if (interface)
     452      gi_base_info_unref (interface);
     453  
     454    gi_base_info_unref ((GIBaseInfo *)type);
     455  
     456    xml_end_element (file, "field");
     457  }
     458  
     459  static void
     460  write_callable_info (const gchar    *ns,
     461  		     GICallableInfo *info,
     462  		     Xml            *file)
     463  {
     464    GITypeInfo *type;
     465  
     466    if (gi_callable_info_can_throw_gerror (info))
     467      xml_printf (file, " throws=\"1\"");
     468  
     469    write_attributes (file, (GIBaseInfo*) info);
     470  
     471    type = gi_callable_info_get_return_type (info);
     472  
     473    xml_start_element (file, "return-value");
     474  
     475    write_ownership_transfer (gi_callable_info_get_caller_owns (info), file);
     476  
     477    if (gi_callable_info_may_return_null (info))
     478      xml_printf (file, " allow-none=\"1\"");
     479  
     480    if (gi_callable_info_skip_return (info))
     481      xml_printf (file, " skip=\"1\"");
     482  
     483    write_return_value_attributes (file, info);
     484  
     485    write_type_info (ns, type, file);
     486  
     487    xml_end_element (file, "return-value");
     488  
     489    if (gi_callable_info_get_n_args (info) <= 0)
     490      return;
     491  
     492    xml_start_element (file, "parameters");
     493    for (guint i = 0; i < gi_callable_info_get_n_args (info); i++)
     494      {
     495        GIArgInfo *arg = gi_callable_info_get_arg (info, i);
     496  
     497        xml_start_element (file, "parameter");
     498        xml_printf (file, " name=\"%s\"",
     499                    gi_base_info_get_name ((GIBaseInfo *) arg));
     500  
     501        write_ownership_transfer (gi_arg_info_get_ownership_transfer (arg), file);
     502  
     503        switch (gi_arg_info_get_direction (arg))
     504  	{
     505  	case GI_DIRECTION_IN:
     506  	  break;
     507  	case GI_DIRECTION_OUT:
     508  	  xml_printf (file, " direction=\"out\" caller-allocates=\"%s\"",
     509  	              gi_arg_info_is_caller_allocates (arg) ? "1" : "0");
     510  	  break;
     511  	case GI_DIRECTION_INOUT:
     512  	  xml_printf (file, " direction=\"inout\"");
     513  	  break;
     514  	default:
     515  	  g_assert_not_reached ();
     516  	}
     517  
     518        if (gi_arg_info_may_be_null (arg))
     519  	xml_printf (file, " allow-none=\"1\"");
     520  
     521        if (gi_arg_info_is_return_value (arg))
     522  	xml_printf (file, " retval=\"1\"");
     523  
     524        if (gi_arg_info_is_optional (arg))
     525  	xml_printf (file, " optional=\"1\"");
     526  
     527        switch (gi_arg_info_get_scope (arg))
     528          {
     529          case GI_SCOPE_TYPE_INVALID:
     530            break;
     531          case GI_SCOPE_TYPE_CALL:
     532            xml_printf (file, " scope=\"call\"");
     533            break;
     534          case GI_SCOPE_TYPE_ASYNC:
     535            xml_printf (file, " scope=\"async\"");
     536            break;
     537          case GI_SCOPE_TYPE_NOTIFIED:
     538            xml_printf (file, " scope=\"notified\"");
     539            break;
     540          case GI_SCOPE_TYPE_FOREVER:
     541            xml_printf (file, " scope=\"forever\"");
     542            break;
     543          default:
     544            g_assert_not_reached ();
     545          }
     546  
     547        if (gi_arg_info_get_closure_index (arg) >= 0)
     548          xml_printf (file, " closure=\"%d\"", gi_arg_info_get_closure_index (arg));
     549  
     550        if (gi_arg_info_get_destroy_index (arg) >= 0)
     551          xml_printf (file, " destroy=\"%d\"", gi_arg_info_get_destroy_index (arg));
     552  
     553        if (gi_arg_info_is_skip (arg))
     554          xml_printf (file, " skip=\"1\"");
     555  
     556        write_attributes (file, (GIBaseInfo*) arg);
     557  
     558        type = gi_arg_info_get_type_info (arg);
     559        write_type_info (ns, type, file);
     560  
     561        xml_end_element (file, "parameter");
     562  
     563        gi_base_info_unref ((GIBaseInfo *)arg);
     564      }
     565  
     566    xml_end_element (file, "parameters");
     567    gi_base_info_unref ((GIBaseInfo *)type);
     568  }
     569  
     570  static void
     571  write_function_info (const gchar    *ns,
     572  		     GIFunctionInfo *info,
     573  		     Xml            *file)
     574  {
     575    GIFunctionInfoFlags flags;
     576    const gchar *tag;
     577    const gchar *name;
     578    const gchar *symbol;
     579    gboolean deprecated;
     580  
     581    flags = gi_function_info_get_flags (info);
     582    name = gi_base_info_get_name ((GIBaseInfo *)info);
     583    symbol = gi_function_info_get_symbol (info);
     584    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
     585  
     586    if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
     587      tag = "constructor";
     588    else if (flags & GI_FUNCTION_IS_METHOD)
     589      tag = "method";
     590    else
     591      tag = "function";
     592  
     593    xml_start_element (file, tag);
     594    xml_printf (file, " name=\"%s\" c:identifier=\"%s\"",
     595                name, symbol);
     596  
     597    if ((flags & GI_FUNCTION_IS_SETTER) || (flags & GI_FUNCTION_IS_GETTER))
     598      {
     599        GIPropertyInfo *property = gi_function_info_get_property (info);
     600  
     601        if (property != NULL)
     602          {
     603            const char *property_name = gi_base_info_get_name ((GIBaseInfo *)property);
     604  
     605            if (flags & GI_FUNCTION_IS_SETTER)
     606              xml_printf (file, " glib:set-property=\"%s\"", property_name);
     607            else if (flags & GI_FUNCTION_IS_GETTER)
     608              xml_printf (file, " glib:get-property=\"%s\"", property_name);
     609  
     610            gi_base_info_unref ((GIBaseInfo *) property);
     611          }
     612      }
     613  
     614    if (deprecated)
     615      xml_printf (file, " deprecated=\"1\"");
     616  
     617    write_callable_info (ns, (GICallableInfo*)info, file);
     618    xml_end_element (file, tag);
     619  }
     620  
     621  static void
     622  write_callback_info (const gchar    *ns,
     623  		     GICallbackInfo *info,
     624  		     Xml            *file)
     625  {
     626    const gchar *name;
     627    gboolean deprecated;
     628  
     629    name = gi_base_info_get_name ((GIBaseInfo *)info);
     630    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
     631  
     632    xml_start_element (file, "callback");
     633    xml_printf (file, " name=\"%s\"", name);
     634  
     635    if (deprecated)
     636      xml_printf (file, " deprecated=\"1\"");
     637  
     638    write_callable_info (ns, (GICallableInfo*)info, file);
     639    xml_end_element (file, "callback");
     640  }
     641  
     642  static void
     643  write_struct_info (const gchar  *ns,
     644  		   GIStructInfo *info,
     645  		   Xml          *file)
     646  {
     647    const gchar *name;
     648    const gchar *type_name;
     649    const gchar *type_init;
     650    const gchar *func;
     651    gboolean deprecated;
     652    gboolean is_gtype_struct;
     653    gboolean foreign;
     654    gint size;
     655    guint n_elts;
     656  
     657    name = gi_base_info_get_name ((GIBaseInfo *)info);
     658    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
     659  
     660    type_name = gi_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
     661    type_init = gi_registered_type_info_get_type_init_function_name ((GIRegisteredTypeInfo*)info);
     662  
     663    if (gi_base_info_get_info_type ((GIBaseInfo *) info) == GI_INFO_TYPE_BOXED)
     664      {
     665        xml_start_element (file, "glib:boxed");
     666        xml_printf (file, " glib:name=\"%s\"", name);
     667      }
     668    else
     669      {
     670        xml_start_element (file, "record");
     671        xml_printf (file, " name=\"%s\"", name);
     672      }
     673  
     674    if (type_name != NULL)
     675      xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
     676  
     677    if (deprecated)
     678      xml_printf (file, " deprecated=\"1\"");
     679  
     680    is_gtype_struct = gi_struct_info_is_gtype_struct (info);
     681    if (is_gtype_struct)
     682      xml_printf (file, " glib:is-gtype-struct=\"1\"");
     683  
     684    func = gi_struct_info_get_copy_function_name (info);
     685    if (func)
     686      xml_printf (file, " copy-function=\"%s\"", func);
     687  
     688    func = gi_struct_info_get_free_function_name (info);
     689    if (func)
     690      xml_printf (file, " free-function=\"%s\"", func);
     691  
     692    write_attributes (file, (GIBaseInfo*) info);
     693  
     694    size = gi_struct_info_get_size (info);
     695    if (file->show_all && size >= 0)
     696      xml_printf (file, " size=\"%d\"", size);
     697  
     698    foreign = gi_struct_info_is_foreign (info);
     699    if (foreign)
     700      xml_printf (file, " foreign=\"1\"");
     701  
     702    n_elts = gi_struct_info_get_n_fields (info) + gi_struct_info_get_n_methods (info);
     703    if (n_elts > 0)
     704      {
     705        for (guint i = 0; i < gi_struct_info_get_n_fields (info); i++)
     706  	{
     707  	  GIFieldInfo *field = gi_struct_info_get_field (info, i);
     708  	  write_field_info (ns, field, NULL, file);
     709  	  gi_base_info_unref ((GIBaseInfo *)field);
     710  	}
     711  
     712        for (guint i = 0; i < gi_struct_info_get_n_methods (info); i++)
     713  	{
     714  	  GIFunctionInfo *function = gi_struct_info_get_method (info, i);
     715  	  write_function_info (ns, function, file);
     716  	  gi_base_info_unref ((GIBaseInfo *)function);
     717  	}
     718  
     719      }
     720  
     721    xml_end_element_unchecked (file);
     722  }
     723  
     724  static void
     725  write_value_info (const gchar *ns,
     726  		  GIValueInfo *info,
     727  		  Xml         *file)
     728  {
     729    const gchar *name;
     730    gint64 value;
     731    gchar *value_str;
     732    gboolean deprecated;
     733  
     734    name = gi_base_info_get_name ((GIBaseInfo *)info);
     735    value = gi_value_info_get_value (info);
     736    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
     737  
     738    xml_start_element (file, "member");
     739    value_str = g_strdup_printf ("%" G_GINT64_FORMAT, value);
     740    xml_printf (file, " name=\"%s\" value=\"%s\"", name, value_str);
     741    g_free (value_str);
     742  
     743    if (deprecated)
     744      xml_printf (file, " deprecated=\"1\"");
     745  
     746    write_attributes (file, (GIBaseInfo*) info);
     747  
     748    xml_end_element (file, "member");
     749  }
     750  
     751  static void
     752  write_constant_value (const gchar *ns,
     753  		      GITypeInfo *type,
     754  		      GIArgument  *value,
     755  		      Xml        *file)
     756  {
     757    switch (gi_type_info_get_tag (type))
     758      {
     759      case GI_TYPE_TAG_BOOLEAN:
     760        xml_printf (file, "%d", value->v_boolean);
     761        break;
     762      case GI_TYPE_TAG_INT8:
     763        xml_printf (file, "%d", value->v_int8);
     764        break;
     765      case GI_TYPE_TAG_UINT8:
     766        xml_printf (file, "%d", value->v_uint8);
     767        break;
     768      case GI_TYPE_TAG_INT16:
     769        xml_printf (file, "%" G_GINT16_FORMAT, value->v_int16);
     770        break;
     771      case GI_TYPE_TAG_UINT16:
     772        xml_printf (file, "%" G_GUINT16_FORMAT, value->v_uint16);
     773        break;
     774      case GI_TYPE_TAG_INT32:
     775        xml_printf (file, "%" G_GINT32_FORMAT, value->v_int32);
     776        break;
     777      case GI_TYPE_TAG_UINT32:
     778        xml_printf (file, "%" G_GUINT32_FORMAT, value->v_uint32);
     779        break;
     780      case GI_TYPE_TAG_INT64:
     781        xml_printf (file, "%" G_GINT64_FORMAT, value->v_int64);
     782        break;
     783      case GI_TYPE_TAG_UINT64:
     784        xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64);
     785        break;
     786      case GI_TYPE_TAG_FLOAT:
     787        xml_printf (file, "%f", (double)value->v_float);
     788        break;
     789      case GI_TYPE_TAG_DOUBLE:
     790        xml_printf (file, "%f", value->v_double);
     791        break;
     792      case GI_TYPE_TAG_UTF8:
     793      case GI_TYPE_TAG_FILENAME:
     794        xml_printf (file, "%s", value->v_string);
     795        break;
     796      default:
     797        g_assert_not_reached ();
     798      }
     799  }
     800  
     801  static void
     802  write_constant_info (const gchar    *ns,
     803  		     GIConstantInfo *info,
     804  		     Xml            *file)
     805  {
     806    GITypeInfo *type;
     807    const gchar *name;
     808    GIArgument value;
     809  
     810    name = gi_base_info_get_name ((GIBaseInfo *)info);
     811  
     812    xml_start_element (file, "constant");
     813    xml_printf (file, " name=\"%s\"", name);
     814  
     815    type = gi_constant_info_get_type_info (info);
     816    xml_printf (file, " value=\"");
     817  
     818    gi_constant_info_get_value (info, &value);
     819    write_constant_value (ns, type, &value, file);
     820    xml_printf (file, "\"");
     821  
     822    write_type_info (ns, type, file);
     823  
     824    write_attributes (file, (GIBaseInfo*) info);
     825  
     826    xml_end_element (file, "constant");
     827  
     828    gi_base_info_unref ((GIBaseInfo *)type);
     829  }
     830  
     831  
     832  static void
     833  write_enum_info (const gchar *ns,
     834  		 GIEnumInfo *info,
     835  		 Xml         *file)
     836  {
     837    const gchar *name;
     838    const gchar *type_name;
     839    const gchar *type_init;
     840    const gchar *error_domain;
     841    gboolean deprecated;
     842  
     843    name = gi_base_info_get_name ((GIBaseInfo *)info);
     844    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
     845  
     846    type_name = gi_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
     847    type_init = gi_registered_type_info_get_type_init_function_name ((GIRegisteredTypeInfo*)info);
     848    error_domain = gi_enum_info_get_error_domain (info);
     849  
     850    if (gi_base_info_get_info_type ((GIBaseInfo *) info) == GI_INFO_TYPE_ENUM)
     851      xml_start_element (file, "enumeration");
     852    else
     853      xml_start_element (file, "bitfield");
     854    xml_printf (file, " name=\"%s\"", name);
     855  
     856    if (type_init)
     857      xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
     858    if (error_domain)
     859      xml_printf (file, " glib:error-domain=\"%s\"", error_domain);
     860  
     861    if (deprecated)
     862      xml_printf (file, " deprecated=\"1\"");
     863  
     864    write_attributes (file, (GIBaseInfo*) info);
     865  
     866    for (guint i = 0; i < gi_enum_info_get_n_values (info); i++)
     867      {
     868        GIValueInfo *value = gi_enum_info_get_value (info, i);
     869        write_value_info (ns, value, file);
     870        gi_base_info_unref ((GIBaseInfo *)value);
     871      }
     872  
     873    xml_end_element_unchecked (file);
     874  }
     875  
     876  static void
     877  write_signal_info (const gchar  *ns,
     878  		   GISignalInfo *info,
     879  		   Xml          *file)
     880  {
     881    GSignalFlags flags;
     882    const gchar *name;
     883    gboolean deprecated;
     884  
     885    name = gi_base_info_get_name ((GIBaseInfo *)info);
     886    flags = gi_signal_info_get_flags (info);
     887    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
     888  
     889    xml_start_element (file, "glib:signal");
     890    xml_printf (file, " name=\"%s\"", name);
     891  
     892    if (deprecated)
     893      xml_printf (file, " deprecated=\"1\"");
     894  
     895    if (flags & G_SIGNAL_RUN_FIRST)
     896      xml_printf (file, " when=\"FIRST\"");
     897    else if (flags & G_SIGNAL_RUN_LAST)
     898      xml_printf (file, " when=\"LAST\"");
     899    else if (flags & G_SIGNAL_RUN_CLEANUP)
     900      xml_printf (file, " when=\"CLEANUP\"");
     901  
     902    if (flags & G_SIGNAL_NO_RECURSE)
     903      xml_printf (file, " no-recurse=\"1\"");
     904  
     905    if (flags & G_SIGNAL_DETAILED)
     906      xml_printf (file, " detailed=\"1\"");
     907  
     908    if (flags & G_SIGNAL_ACTION)
     909      xml_printf (file, " action=\"1\"");
     910  
     911    if (flags & G_SIGNAL_NO_HOOKS)
     912      xml_printf (file, " no-hooks=\"1\"");
     913  
     914    write_callable_info (ns, (GICallableInfo*)info, file);
     915  
     916    xml_end_element (file, "glib:signal");
     917  }
     918  
     919  static void
     920  write_vfunc_info (const gchar *ns,
     921  		  GIVFuncInfo *info,
     922  		  Xml         *file)
     923  {
     924    GIVFuncInfoFlags flags;
     925    const gchar *name;
     926    GIFunctionInfo *invoker;
     927    gboolean deprecated;
     928    gint offset;
     929  
     930    name = gi_base_info_get_name ((GIBaseInfo *)info);
     931    flags = gi_vfunc_info_get_flags (info);
     932    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
     933    offset = gi_vfunc_info_get_offset (info);
     934    invoker = gi_vfunc_info_get_invoker (info);
     935  
     936    xml_start_element (file, "virtual-method");
     937    xml_printf (file, " name=\"%s\"", name);
     938  
     939    if (deprecated)
     940      xml_printf (file, " deprecated=\"1\"");
     941  
     942    if (flags & GI_VFUNC_MUST_CHAIN_UP)
     943      xml_printf (file, " must-chain-up=\"1\"");
     944  
     945    if (flags & GI_VFUNC_MUST_OVERRIDE)
     946      xml_printf (file, " override=\"always\"");
     947    else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE)
     948      xml_printf (file, " override=\"never\"");
     949  
     950    xml_printf (file, " offset=\"%d\"", offset);
     951  
     952    if (invoker)
     953      {
     954        xml_printf (file, " invoker=\"%s\"", gi_base_info_get_name ((GIBaseInfo*)invoker));
     955        gi_base_info_unref ((GIBaseInfo *)invoker);
     956      }
     957  
     958    write_callable_info (ns, (GICallableInfo*)info, file);
     959  
     960    xml_end_element (file, "virtual-method");
     961  }
     962  
     963  static void
     964  write_property_info (const gchar    *ns,
     965  		     GIPropertyInfo *info,
     966  		     Xml            *file)
     967  {
     968    GParamFlags flags;
     969    const gchar *name;
     970    gboolean deprecated;
     971    GITypeInfo *type;
     972  
     973    name = gi_base_info_get_name ((GIBaseInfo *)info);
     974    flags = gi_property_info_get_flags (info);
     975    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
     976  
     977    xml_start_element (file, "property");
     978    xml_printf (file, " name=\"%s\"", name);
     979  
     980    if (deprecated)
     981      xml_printf (file, " deprecated=\"1\"");
     982  
     983    /* Properties are assumed to be read-only (see also girwriter.py) */
     984    if (!(flags & G_PARAM_READABLE))
     985      xml_printf (file, " readable=\"0\"");
     986    if (flags & G_PARAM_WRITABLE)
     987      xml_printf (file, " writable=\"1\"");
     988  
     989    if (flags & G_PARAM_CONSTRUCT)
     990      xml_printf (file, " construct=\"1\"");
     991  
     992    if (flags & G_PARAM_CONSTRUCT_ONLY)
     993      xml_printf (file, " construct-only=\"1\"");
     994  
     995    if (flags & G_PARAM_READABLE)
     996      {
     997        GIFunctionInfo *getter = gi_property_info_get_getter (info);
     998  
     999        if (getter != NULL)
    1000          {
    1001            xml_printf (file, " getter=\"%s\"", gi_base_info_get_name ((GIBaseInfo *) getter));
    1002            gi_base_info_unref ((GIBaseInfo *) getter);
    1003          }
    1004      }
    1005  
    1006    if (flags & G_PARAM_WRITABLE)
    1007      {
    1008        GIFunctionInfo *setter = gi_property_info_get_setter (info);
    1009  
    1010        if (setter != NULL)
    1011          {
    1012            xml_printf (file, " setter=\"%s\"", gi_base_info_get_name ((GIBaseInfo *) setter));
    1013            gi_base_info_unref ((GIBaseInfo *) setter);
    1014          }
    1015      }
    1016  
    1017    write_ownership_transfer (gi_property_info_get_ownership_transfer (info), file);
    1018  
    1019    write_attributes (file, (GIBaseInfo*) info);
    1020  
    1021    type = gi_property_info_get_type_info (info);
    1022  
    1023    write_type_info (ns, type, file);
    1024  
    1025    xml_end_element (file, "property");
    1026  }
    1027  
    1028  static void
    1029  write_object_info (const gchar  *ns,
    1030  		   GIObjectInfo *info,
    1031  		   Xml          *file)
    1032  {
    1033    const gchar *name;
    1034    const gchar *type_name;
    1035    const gchar *type_init;
    1036    const gchar *func;
    1037    gboolean deprecated;
    1038    gboolean is_abstract;
    1039    gboolean is_fundamental;
    1040    gboolean is_final;
    1041    GIObjectInfo *pnode;
    1042    GIStructInfo *class_struct;
    1043  
    1044    name = gi_base_info_get_name ((GIBaseInfo *)info);
    1045    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
    1046    is_abstract = gi_object_info_get_abstract (info);
    1047    is_fundamental = gi_object_info_get_fundamental (info);
    1048    is_final = gi_object_info_get_final (info);
    1049  
    1050    type_name = gi_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
    1051    type_init = gi_registered_type_info_get_type_init_function_name ((GIRegisteredTypeInfo*)info);
    1052    xml_start_element (file, "class");
    1053    xml_printf (file, " name=\"%s\"", name);
    1054  
    1055    pnode = gi_object_info_get_parent (info);
    1056    if (pnode)
    1057      {
    1058        write_type_name_attribute (ns, (GIBaseInfo *)pnode, "parent", file);
    1059        gi_base_info_unref ((GIBaseInfo *)pnode);
    1060      }
    1061  
    1062    class_struct = gi_object_info_get_class_struct (info);
    1063    if (class_struct)
    1064      {
    1065        write_type_name_attribute (ns, (GIBaseInfo*) class_struct, "glib:type-struct", file);
    1066        gi_base_info_unref ((GIBaseInfo*)class_struct);
    1067      }
    1068  
    1069    if (is_abstract)
    1070      xml_printf (file, " abstract=\"1\"");
    1071  
    1072    if (is_final)
    1073      xml_printf (file, " final=\"1\"");
    1074  
    1075    xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
    1076  
    1077    if (is_fundamental)
    1078      xml_printf (file, " glib:fundamental=\"1\"");
    1079  
    1080    func = gi_object_info_get_unref_function_name (info);
    1081    if (func)
    1082      xml_printf (file, " glib:unref-function=\"%s\"", func);
    1083  
    1084    func = gi_object_info_get_ref_function_name (info);
    1085    if (func)
    1086      xml_printf (file, " glib:ref-function=\"%s\"", func);
    1087  
    1088    func = gi_object_info_get_set_value_function_name (info);
    1089    if (func)
    1090      xml_printf (file, " glib:set-value-function=\"%s\"", func);
    1091  
    1092    func = gi_object_info_get_get_value_function_name (info);
    1093    if (func)
    1094      xml_printf (file, " glib:get-value-function=\"%s\"", func);
    1095  
    1096    if (deprecated)
    1097      xml_printf (file, " deprecated=\"1\"");
    1098  
    1099    write_attributes (file, (GIBaseInfo*) info);
    1100  
    1101    if (gi_object_info_get_n_interfaces (info) > 0)
    1102      {
    1103        for (guint i = 0; i < gi_object_info_get_n_interfaces (info); i++)
    1104  	{
    1105  	  GIInterfaceInfo *imp = gi_object_info_get_interface (info, i);
    1106            xml_start_element (file, "implements");
    1107  	  write_type_name_attribute (ns, (GIBaseInfo *)imp, "name", file);
    1108            xml_end_element (file, "implements");
    1109  	  gi_base_info_unref ((GIBaseInfo*)imp);
    1110  	}
    1111      }
    1112  
    1113    for (guint i = 0; i < gi_object_info_get_n_fields (info); i++)
    1114      {
    1115        GIFieldInfo *field = gi_object_info_get_field (info, i);
    1116        write_field_info (ns, field, NULL, file);
    1117        gi_base_info_unref ((GIBaseInfo *)field);
    1118      }
    1119  
    1120    for (guint i = 0; i < gi_object_info_get_n_methods (info); i++)
    1121      {
    1122        GIFunctionInfo *function = gi_object_info_get_method (info, i);
    1123        write_function_info (ns, function, file);
    1124        gi_base_info_unref ((GIBaseInfo *)function);
    1125      }
    1126  
    1127    for (guint i = 0; i < gi_object_info_get_n_properties (info); i++)
    1128      {
    1129        GIPropertyInfo *prop = gi_object_info_get_property (info, i);
    1130        write_property_info (ns, prop, file);
    1131        gi_base_info_unref ((GIBaseInfo *)prop);
    1132      }
    1133  
    1134    for (guint i = 0; i < gi_object_info_get_n_signals (info); i++)
    1135      {
    1136        GISignalInfo *signal = gi_object_info_get_signal (info, i);
    1137        write_signal_info (ns, signal, file);
    1138        gi_base_info_unref ((GIBaseInfo *)signal);
    1139      }
    1140  
    1141    for (guint i = 0; i < gi_object_info_get_n_vfuncs (info); i++)
    1142      {
    1143        GIVFuncInfo *vfunc = gi_object_info_get_vfunc (info, i);
    1144        write_vfunc_info (ns, vfunc, file);
    1145        gi_base_info_unref ((GIBaseInfo *)vfunc);
    1146      }
    1147  
    1148    for (guint i = 0; i < gi_object_info_get_n_constants (info); i++)
    1149      {
    1150        GIConstantInfo *constant = gi_object_info_get_constant (info, i);
    1151        write_constant_info (ns, constant, file);
    1152        gi_base_info_unref ((GIBaseInfo *)constant);
    1153      }
    1154  
    1155    xml_end_element (file, "class");
    1156  }
    1157  
    1158  static void
    1159  write_interface_info (const gchar     *ns,
    1160  		      GIInterfaceInfo *info,
    1161  		      Xml             *file)
    1162  {
    1163    const gchar *name;
    1164    const gchar *type_name;
    1165    const gchar *type_init;
    1166    GIStructInfo *class_struct;
    1167    gboolean deprecated;
    1168  
    1169    name = gi_base_info_get_name ((GIBaseInfo *)info);
    1170    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
    1171  
    1172    type_name = gi_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
    1173    type_init = gi_registered_type_info_get_type_init_function_name ((GIRegisteredTypeInfo*)info);
    1174    xml_start_element (file, "interface");
    1175    xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"",
    1176  	     name, type_name, type_init);
    1177  
    1178    class_struct = gi_interface_info_get_iface_struct (info);
    1179    if (class_struct)
    1180      {
    1181        write_type_name_attribute (ns, (GIBaseInfo*) class_struct, "glib:type-struct", file);
    1182        gi_base_info_unref ((GIBaseInfo*)class_struct);
    1183      }
    1184  
    1185    if (deprecated)
    1186      xml_printf (file, " deprecated=\"1\"");
    1187  
    1188    write_attributes (file, (GIBaseInfo*) info);
    1189  
    1190    if (gi_interface_info_get_n_prerequisites (info) > 0)
    1191      {
    1192        for (guint i = 0; i < gi_interface_info_get_n_prerequisites (info); i++)
    1193  	{
    1194  	  GIBaseInfo *req = gi_interface_info_get_prerequisite (info, i);
    1195  
    1196  	  xml_start_element (file, "prerequisite");
    1197  	  write_type_name_attribute (ns, req, "name", file);
    1198  
    1199            xml_end_element_unchecked (file);
    1200  	  gi_base_info_unref (req);
    1201  	}
    1202      }
    1203  
    1204    for (guint i = 0; i < gi_interface_info_get_n_methods (info); i++)
    1205      {
    1206        GIFunctionInfo *function = gi_interface_info_get_method (info, i);
    1207        write_function_info (ns, function, file);
    1208        gi_base_info_unref ((GIBaseInfo *)function);
    1209      }
    1210  
    1211    for (guint i = 0; i < gi_interface_info_get_n_properties (info); i++)
    1212      {
    1213        GIPropertyInfo *prop = gi_interface_info_get_property (info, i);
    1214        write_property_info (ns, prop, file);
    1215        gi_base_info_unref ((GIBaseInfo *)prop);
    1216      }
    1217  
    1218    for (guint i = 0; i < gi_interface_info_get_n_signals (info); i++)
    1219      {
    1220        GISignalInfo *signal = gi_interface_info_get_signal (info, i);
    1221        write_signal_info (ns, signal, file);
    1222        gi_base_info_unref ((GIBaseInfo *)signal);
    1223      }
    1224  
    1225    for (guint i = 0; i < gi_interface_info_get_n_vfuncs (info); i++)
    1226      {
    1227        GIVFuncInfo *vfunc = gi_interface_info_get_vfunc (info, i);
    1228        write_vfunc_info (ns, vfunc, file);
    1229        gi_base_info_unref ((GIBaseInfo *)vfunc);
    1230      }
    1231  
    1232    for (guint i = 0; i < gi_interface_info_get_n_constants (info); i++)
    1233      {
    1234        GIConstantInfo *constant = gi_interface_info_get_constant (info, i);
    1235        write_constant_info (ns, constant, file);
    1236        gi_base_info_unref ((GIBaseInfo *)constant);
    1237      }
    1238  
    1239    xml_end_element (file, "interface");
    1240  }
    1241  
    1242  static void
    1243  write_union_info (const gchar *ns,
    1244  		  GIUnionInfo *info,
    1245  		  Xml         *file)
    1246  {
    1247    const gchar *name;
    1248    const gchar *type_name;
    1249    const gchar *type_init;
    1250    const gchar *func;
    1251    gboolean deprecated;
    1252    gsize size;
    1253  
    1254    name = gi_base_info_get_name ((GIBaseInfo *)info);
    1255    deprecated = gi_base_info_is_deprecated ((GIBaseInfo *)info);
    1256  
    1257    type_name = gi_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
    1258    type_init = gi_registered_type_info_get_type_init_function_name ((GIRegisteredTypeInfo*)info);
    1259  
    1260    xml_start_element (file, "union");
    1261    xml_printf (file, " name=\"%s\"", name);
    1262  
    1263    if (type_name)
    1264      xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
    1265  
    1266    if (deprecated)
    1267      xml_printf (file, " deprecated=\"1\"");
    1268  
    1269    size = gi_union_info_get_size (info);
    1270    if (file->show_all)
    1271      xml_printf (file, " size=\"%" G_GSIZE_FORMAT "\"", size);
    1272  
    1273    func = gi_union_info_get_copy_function_name (info);
    1274    if (func)
    1275      xml_printf (file, " copy-function=\"%s\"", func);
    1276  
    1277    func = gi_union_info_get_free_function_name (info);
    1278    if (func)
    1279      xml_printf (file, " free-function=\"%s\"", func);
    1280  
    1281    write_attributes (file, (GIBaseInfo*) info);
    1282  
    1283    if (gi_union_info_is_discriminated (info))
    1284      {
    1285        guint offset;
    1286        GITypeInfo *type;
    1287  
    1288        offset = gi_union_info_get_discriminator_offset (info);
    1289        type = gi_union_info_get_discriminator_type (info);
    1290  
    1291        xml_start_element (file, "discriminator");
    1292        xml_printf (file, " offset=\"%d\" type=\"", offset);
    1293        write_type_info (ns, type, file);
    1294        xml_end_element (file, "discriminator");
    1295        gi_base_info_unref ((GIBaseInfo *)type);
    1296      }
    1297  
    1298    for (guint i = 0; i < gi_union_info_get_n_fields (info); i++)
    1299      {
    1300        GIFieldInfo *field = gi_union_info_get_field (info, i);
    1301        GIConstantInfo *constant = gi_union_info_get_discriminator (info, i);
    1302        write_field_info (ns, field, constant, file);
    1303        gi_base_info_unref ((GIBaseInfo *)field);
    1304        if (constant)
    1305  	gi_base_info_unref ((GIBaseInfo *)constant);
    1306      }
    1307  
    1308    for (guint i = 0; i < gi_union_info_get_n_methods (info); i++)
    1309      {
    1310        GIFunctionInfo *function = gi_union_info_get_method (info, i);
    1311        write_function_info (ns, function, file);
    1312        gi_base_info_unref ((GIBaseInfo *)function);
    1313      }
    1314  
    1315    xml_end_element (file, "union");
    1316  }
    1317  
    1318  
    1319  /**
    1320   * gi_ir_writer_write:
    1321   * @filename: (type filename): filename to write to
    1322   * @ns: GIR namespace to write
    1323   * @needs_prefix: if the filename needs prefixing
    1324   * @show_all: if field size calculations should be included
    1325   *
    1326   * Writes the output of a typelib represented by @ns
    1327   * into a GIR xml file named @filename.
    1328   *
    1329   * Since: 2.80
    1330   */
    1331  void
    1332  gi_ir_writer_write (const char *filename,
    1333                      const char *ns,
    1334                      gboolean    needs_prefix,
    1335                      gboolean    show_all)
    1336  {
    1337    FILE *ofile;
    1338    gint i, j;
    1339    char **dependencies;
    1340    GIRepository *repository;
    1341    Xml *xml;
    1342  
    1343    repository = gi_repository_get_default ();
    1344  
    1345    if (filename == NULL)
    1346      ofile = stdout;
    1347    else
    1348      {
    1349        gchar *full_filename;
    1350  
    1351        if (needs_prefix)
    1352  	full_filename = g_strdup_printf ("%s-%s", ns, filename);
    1353        else
    1354  	full_filename = g_strdup (filename);
    1355        ofile = g_fopen (filename, "w");
    1356  
    1357        if (ofile == NULL)
    1358  	{
    1359  	  g_fprintf (stderr, "failed to open '%s': %s\n",
    1360  		     full_filename, g_strerror (errno));
    1361  	  g_free (full_filename);
    1362  
    1363  	  return;
    1364  	}
    1365  
    1366        g_free (full_filename);
    1367      }
    1368  
    1369    xml = xml_open (ofile);
    1370    xml->show_all = show_all;
    1371    xml_printf (xml, "<?xml version=\"1.0\"?>\n");
    1372    xml_start_element (xml, "repository");
    1373    xml_printf (xml, " version=\"1.0\"\n"
    1374  	      "            xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n"
    1375  	      "            xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n"
    1376  	      "            xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
    1377  
    1378    dependencies = gi_repository_get_immediate_dependencies (repository, ns);
    1379    if (dependencies != NULL)
    1380      {
    1381        for (i = 0; dependencies[i]; i++)
    1382  	{
    1383  	  char **parts = g_strsplit (dependencies[i], "-", 2);
    1384  	  xml_start_element (xml, "include");
    1385  	  xml_printf (xml, " name=\"%s\" version=\"%s\"", parts[0], parts[1]);
    1386  	  xml_end_element (xml, "include");
    1387  	  g_strfreev (parts);
    1388  	}
    1389      }
    1390  
    1391    if (TRUE)
    1392      {
    1393        const gchar *shared_library;
    1394        const gchar *c_prefix;
    1395        const char *cur_ns = ns;
    1396        const char *cur_version;
    1397        gint n_infos;
    1398  
    1399        cur_version = gi_repository_get_version (repository, cur_ns);
    1400  
    1401        shared_library = gi_repository_get_shared_library (repository, cur_ns);
    1402        c_prefix = gi_repository_get_c_prefix (repository, cur_ns);
    1403        xml_start_element (xml, "namespace");
    1404        xml_printf (xml, " name=\"%s\" version=\"%s\"", cur_ns, cur_version);
    1405        if (shared_library)
    1406          xml_printf (xml, " shared-library=\"%s\"", shared_library);
    1407        if (c_prefix)
    1408          xml_printf (xml, " c:prefix=\"%s\"", c_prefix);
    1409  
    1410        n_infos = gi_repository_get_n_infos (repository, cur_ns);
    1411        for (j = 0; j < n_infos; j++)
    1412  	{
    1413  	  GIBaseInfo *info = gi_repository_get_info (repository, cur_ns, j);
    1414  	  switch (gi_base_info_get_info_type (info))
    1415  	    {
    1416  	    case GI_INFO_TYPE_FUNCTION:
    1417  	      write_function_info (ns, (GIFunctionInfo *)info, xml);
    1418  	      break;
    1419  
    1420  	    case GI_INFO_TYPE_CALLBACK:
    1421  	      write_callback_info (ns, (GICallbackInfo *)info, xml);
    1422  	      break;
    1423  
    1424  	    case GI_INFO_TYPE_STRUCT:
    1425  	    case GI_INFO_TYPE_BOXED:
    1426  	      write_struct_info (ns, (GIStructInfo *)info, xml);
    1427  	      break;
    1428  
    1429  	    case GI_INFO_TYPE_UNION:
    1430  	      write_union_info (ns, (GIUnionInfo *)info, xml);
    1431  	      break;
    1432  
    1433  	    case GI_INFO_TYPE_ENUM:
    1434  	    case GI_INFO_TYPE_FLAGS:
    1435  	      write_enum_info (ns, (GIEnumInfo *)info, xml);
    1436  	      break;
    1437  
    1438  	    case GI_INFO_TYPE_CONSTANT:
    1439  	      write_constant_info (ns, (GIConstantInfo *)info, xml);
    1440  	      break;
    1441  
    1442  	    case GI_INFO_TYPE_OBJECT:
    1443  	      write_object_info (ns, (GIObjectInfo *)info, xml);
    1444  	      break;
    1445  
    1446  	    case GI_INFO_TYPE_INTERFACE:
    1447  	      write_interface_info (ns, (GIInterfaceInfo *)info, xml);
    1448  	      break;
    1449  
    1450  	    default:
    1451  	      g_error ("unknown info type %d\n", gi_base_info_get_info_type (info));
    1452  	    }
    1453  
    1454  	  gi_base_info_unref (info);
    1455  	}
    1456  
    1457        xml_end_element (xml, "namespace");
    1458      }
    1459  
    1460    xml_end_element (xml, "repository");
    1461  
    1462    xml_free (xml);
    1463  }