Add support for foreign structs
[gnome.gobject-introspection] / tools / generate.c
index 6991ba3..b813b12 100644 (file)
@@ -1,7 +1,9 @@
+
 /* -*- 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
 /* FIXME: Avoid global */
 static gchar *output = NULL;
 gchar **includedirs = NULL;
+static gboolean show_all = FALSE;
 
 typedef struct {
   FILE *file;
+  GSList *stack;
 } Xml;
 
+typedef struct {
+  char *name;
+  guint has_children : 1;
+} XmlElement;
+
+static XmlElement *
+xml_element_new (const char *name)
+{
+  XmlElement *elem;
+
+  elem = g_new (XmlElement, 1);
+  elem->name = g_strdup (name);
+  elem->has_children = FALSE;
+  return elem;
+}
+
+static void
+xml_element_free (XmlElement *elem)
+{
+  g_free (elem->name);
+  g_free (elem);
+}
+
 static void
 xml_printf (Xml *xml, const char *fmt, ...)
 {
   va_list ap;
+  char *s;
 
   va_start (ap, fmt);
-  vfprintf (xml->file, fmt, ap);
+  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)
 {
@@ -54,6 +131,7 @@ xml_open (FILE *file)
 
   xml = g_new (Xml, 1);
   xml->file = file;
+  xml->stack = NULL;
 
   return xml;
 }
@@ -61,6 +139,7 @@ xml_open (FILE *file)
 static void
 xml_close (Xml *xml)
 {
+  g_assert (xml->stack == NULL);
   if (xml->file != NULL)
     {
       fflush (xml->file);
@@ -78,17 +157,17 @@ xml_free (Xml *xml)
 }
 
 
-static void 
+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_critical ("Found unresolved type '%s' '%s'\n",
              g_base_info_get_name (info), g_base_info_get_namespace (info));
 }
 
-static void 
+static void
 write_type_name (const gchar *namespace,
                 GIBaseInfo  *info,
                 Xml         *file)
@@ -99,114 +178,139 @@ write_type_name (const gchar *namespace,
   xml_printf (file, "%s", g_base_info_get_name (info));
 }
 
+static void
+write_type_name_attribute (const gchar *namespace,
+                          GIBaseInfo  *info,
+                          const char  *attr_name,
+                          Xml         *file)
+{
+  xml_printf (file, " %s=\"", attr_name);
+  write_type_name (namespace, info, file);
+  xml_printf (file, "\"");
+}
+
 static void
 write_type_info (const gchar *namespace,
-                GITypeInfo  *info, 
+                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) 
+  if (tag == GI_TYPE_TAG_VOID)
     {
-      if (is_pointer)
-       xml_printf (file, "%s", "any");
-      else
-       xml_printf (file, "%s", "none");
-    } 
+      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_printf (file, "%s", g_type_tag_to_string (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;
+      gint length, size;
+
+      xml_start_element (file, "array");
 
       type = g_type_info_get_param_type (info, 0);
-      write_type_info (namespace, type, file);
-      xml_printf (file, "[");
 
       length = g_type_info_get_array_length (info);
-      
       if (length >= 0)
-       xml_printf (file, "length=%d", length);
-      
+        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, "%szero-terminated=1", length >= 0 ? "," : "");
-      
-     xml_printf (file, "]");
+       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);
-      write_type_name (namespace, iface, file);
+      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);
-      xml_printf (file, "GLib.List");
       if (type)
        {
-         xml_printf (file, "<");
          write_type_info (namespace, type, file);
-         xml_printf (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);
-      xml_printf (file, "GLib.SList");
       if (type)
        {
-         xml_printf (file, "<");
          write_type_info (namespace, type, file);
-         xml_printf (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);
-      xml_printf (file, "GLib.HashTable");
       if (type)
        {
-         xml_printf (file, "<");
          write_type_info (namespace, type, file);
          g_base_info_unref ((GIBaseInfo *)type);
          type = g_type_info_get_param_type (info, 1);
-         xml_printf (file, ",");
          write_type_info (namespace, type, file);
-         xml_printf (file, ">");
          g_base_info_unref ((GIBaseInfo *)type);
        }
+      xml_end_element (file, "type");
     }
-  else if (tag == GI_TYPE_TAG_ERROR) 
+  else if (tag == GI_TYPE_TAG_ERROR)
     {
       gint n;
 
-      xml_printf (file, "GLib.Error");
+      xml_start_element (file, "type");
+      xml_printf (file, " name=\"GLib.Error\"");
+
       n = g_type_info_get_n_error_domains (info);
       if (n > 0)
        {
-         xml_printf (file, "<");
          for (i = 0; i < n; i++)
            {
              GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i);
-             if (i > 0)
-               xml_printf (file, ",");
-             write_type_name (namespace, (GIBaseInfo *)ed, file);
+             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_printf (file, ">");
        }
+
+      xml_end_element (file, "type");
     }
   else
     {
@@ -216,11 +320,31 @@ write_type_info (const gchar *namespace,
 }
 
 static void
-write_constant_value (const gchar *namespace, 
+write_attributes (Xml *file,
+                   GIBaseInfo *info)
+{
+  GIAttributeIter iter = { 0, };
+  char *name, *value;
+
+  while (g_base_info_iterate_attributes (info, &iter, &name, &value))
+    {
+      xml_start_element (file, "attribute");
+      xml_printf (file, " name=\"%s\" value=\"%s\"", name, value);
+      xml_end_element (file, "attribute");
+    }
+}
+
+static void
+write_constant_value (const gchar *namespace,
                      GITypeInfo *info,
                      GArgument *argument,
                      Xml *file);
 
+static void
+write_callback_info (const gchar    *namespace,
+                    GICallbackInfo *info,
+                    Xml            *file);
+
 static void
 write_field_info (const gchar *namespace,
                  GIFieldInfo *info,
@@ -232,22 +356,29 @@ write_field_info (const gchar *namespace,
   gint size;
   gint offset;
   GITypeInfo *type;
-  GArgument value; 
+  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_printf (file,
-            "      <field name=\"%s\" readable=\"%s\" writable=\"%s\"",
-            name, 
-            flags & GI_FIELD_IS_READABLE ? "1" : "0", 
-            flags & GI_FIELD_IS_WRITABLE ? "1" : "0");
+  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);
 
-  xml_printf (file, " offset=\"%d\"", offset);
+  write_attributes (file, (GIBaseInfo*) info);
 
   type = g_field_info_get_type (info);
 
@@ -260,150 +391,163 @@ write_field_info (const gchar *namespace,
       xml_printf (file, "\"");
     }
 
-  xml_printf (file,">\n");
-
-  xml_printf (file, "        <type name=\"");
+  if (show_all)
+    {
+      if (offset >= 0)
+        xml_printf (file, "offset=\"%d\"", offset);
+    }
 
-  write_type_info (namespace, type, file);
-  g_base_info_unref ((GIBaseInfo *)type);
+  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);
 
-  xml_printf (file, "\"/>\n");
+  if (interface)
+    g_base_info_unref (interface);
 
-  xml_printf (file,  "      </field>\n");
+  g_base_info_unref ((GIBaseInfo *)type);
 
+  xml_end_element (file, "field");
 }
 
-static void 
+static void
 write_callable_info (const gchar    *namespace,
                     GICallableInfo *info,
-                    Xml            *file,
-                    gint            indent)
+                    Xml            *file)
 {
   GITypeInfo *type;
   gint i;
 
-  type = g_callable_info_get_return_type (info);
+  write_attributes (file, (GIBaseInfo*) info);
 
-  xml_printf (file, ">\n");
+  type = g_callable_info_get_return_type (info);
 
-  xml_printf (file, "%*s  <return-value", indent, "");
+  xml_start_element (file, "return-value");
 
-  if (g_type_info_is_pointer (type))
+  switch (g_callable_info_get_caller_owns (info))
     {
-      switch (g_callable_info_get_caller_owns (info))
-       {
-       case GI_TRANSFER_NOTHING:
-         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 ();
-       }
+    case GI_TRANSFER_NOTHING:
+      xml_printf (file, " transfer-ownership=\"none\"");
+      break;
+    case GI_TRANSFER_CONTAINER:
+      xml_printf (file, " transfer-ownership=\"container\"");
+      break;
+    case GI_TRANSFER_EVERYTHING:
+      xml_printf (file, " transfer-ownership=\"full\"");
+      break;
+    default:
+      g_assert_not_reached ();
     }
-  
-  if (g_callable_info_may_return_null (info))
-    xml_printf (file, " null-ok=\"1\"");
-
-  xml_printf (file, ">\n");
 
-  xml_printf (file, "%*s  <type name=\"", indent + 2, "");
+  if (g_callable_info_may_return_null (info))
+    xml_printf (file, " allow-none=\"1\"");
 
   write_type_info (namespace, type, file);
 
-  xml_printf (file, "\"/>\n");
+  xml_end_element (file, "return-value");
 
-  xml_printf (file, "%*s  </return-value>\n", indent, "");
-       
   if (g_callable_info_get_n_args (info) <= 0)
     return;
 
-  xml_printf (file, "%*s  <parameters>\n", indent, "");
+  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_printf (file, "%*s    <parameter name=\"%s\"",
-                indent, "", g_base_info_get_name ((GIBaseInfo *) arg));
-      
+
+      xml_start_element (file, "parameter");
+      xml_printf (file, " name=\"%s\"",
+                  g_base_info_get_name ((GIBaseInfo *) arg));
+
       switch (g_arg_info_get_ownership_transfer (arg))
        {
        case GI_TRANSFER_NOTHING:
+         xml_printf (file, " transfer-ownership=\"none\"");
          break;
        case GI_TRANSFER_CONTAINER:
-         xml_printf (file, " transfer=\"container\"");
+         xml_printf (file, " transfer-ownership=\"container\"");
          break;
        case GI_TRANSFER_EVERYTHING:
-         xml_printf (file, " transfer=\"full\"");
+         xml_printf (file, " transfer-ownership=\"full\"");
          break;
        default:
          g_assert_not_reached ();
        }
-      
-      xml_printf (file, " direction=\"");
+
       switch (g_arg_info_get_direction (arg))
        {
        case GI_DIRECTION_IN:
-         xml_printf (file, "in");
          break;
        case GI_DIRECTION_OUT:
-         xml_printf (file, "out");
+         xml_printf (file, " direction=\"out\"");
          break;
        case GI_DIRECTION_INOUT:
-         xml_printf (file, "inout");
+         xml_printf (file, " direction=\"inout\"");
          break;
        }
-      xml_printf (file, "\"");
-      
+
       if (g_arg_info_may_be_null (arg))
-       xml_printf (file, " null-ok=\"1\"");
-      
+       xml_printf (file, " allow-none=\"1\"");
+
       if (g_arg_info_is_dipper (arg))
        xml_printf (file, " dipper=\"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\"");
-      
-      xml_printf (file, ">\n");
-      
-      xml_printf (file, "%*s    <type name=\"", indent+2, "");
+
+      switch (g_arg_info_get_scope (arg))
+        {
+        case GI_SCOPE_TYPE_INVALID:
+          break;
+        case GI_SCOPE_TYPE_CALL:
+          xml_printf (file, " scope=\"call\"");
+          break;
+        case GI_SCOPE_TYPE_ASYNC:
+          xml_printf (file, " scope=\"async\"");
+          break;
+        case GI_SCOPE_TYPE_NOTIFIED:
+          xml_printf (file, " scope=\"notified\"");
+          break;
+        }
+
+      if (g_arg_info_get_closure (arg) >= 0)
+        xml_printf (file, " closure=\"%d\"", g_arg_info_get_closure (arg));
+
+      if (g_arg_info_get_destroy (arg) >= 0)
+        xml_printf (file, " destroy=\"%d\"", g_arg_info_get_destroy (arg));
 
       type = g_arg_info_get_type (arg);
       write_type_info (namespace, type, file);
 
-      xml_printf (file, "\"/>\n");
-      
-      xml_printf (file, "%*s    </parameter>\n", indent, "");
+      xml_end_element (file, "parameter");
 
       g_base_info_unref ((GIBaseInfo *)arg);
     }
-  
-  xml_printf (file, "%*s  </parameters>\n", indent, "");
+
+  xml_end_element (file, "parameters");
   g_base_info_unref ((GIBaseInfo *)type);
 }
 
 static void
 write_function_info (const gchar    *namespace,
                     GIFunctionInfo *info,
-                    Xml            *file,
-                    gint            indent)
+                    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";
@@ -411,27 +555,30 @@ write_function_info (const gchar    *namespace,
     tag = "method";
   else
     tag = "function";
-       
-  xml_printf (file, "%*s<%s name=\"%s\" c:identifier=\"%s\"",
-              indent, "", tag, name, symbol);
-       
+
+  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\"");
 
-  write_callable_info (namespace, (GICallableInfo*)info, file, indent);
-  xml_printf (file, "%*s</%s>\n", indent, "", tag);
+  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,
-                    gint            indent)
+                    Xml            *file)
 {
   const gchar *name;
   gboolean deprecated;
@@ -439,13 +586,14 @@ write_callback_info (const gchar    *namespace,
   name = g_base_info_get_name ((GIBaseInfo *)info);
   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
 
-  xml_printf (file, "%*s<callback name=\"%s\"", indent, "", name);
-       
+  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, indent);
-  xml_printf (file, "%*s</callback>\n", indent, "");
+
+  write_callable_info (namespace, (GICallableInfo*)info, file);
+  xml_end_element (file, "callback");
 }
 
 static void
@@ -457,7 +605,10 @@ write_struct_info (const gchar  *namespace,
   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);
@@ -465,48 +616,58 @@ write_struct_info (const gchar  *namespace,
 
   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_printf (file, "    <glib:boxed glib:name=\"%s\"", name);
+      xml_start_element (file, "glib:boxed");
+      xml_printf (file, " glib:name=\"%s\"", name);
     }
   else
-    xml_printf (file, "    <record name=\"%s\"", name);
-  
+    {
+      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 (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)
     {
-      xml_printf (file, ">\n");
-      
       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, 6);
+         write_function_info (namespace, function, file);
          g_base_info_unref ((GIBaseInfo *)function);
        }
-      
-      if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED)
-       xml_printf (file, "    </glib:boxed>\n");
-      else
-       xml_printf (file, "    </record>\n");
-    } 
-  else
-    {
-      xml_printf (file, "/>\n");
+
     }
+
+  xml_end_element_unchecked (file);
 }
 
 static void
@@ -522,16 +683,19 @@ write_value_info (const gchar *namespace,
   value = g_value_info_get_value (info);
   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
 
-  xml_printf (file, "      <member name=\"%s\" value=\"%ld\"", name, value);
+  xml_start_element (file, "member");
+  xml_printf (file, " name=\"%s\" value=\"%ld\"", name, value);
 
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
-  
-  xml_printf (file, " />\n");
+
+  write_attributes (file, (GIBaseInfo*) info);
+
+  xml_end_element (file, "member");
 }
 
 static void
-write_constant_value (const gchar *namespace, 
+write_constant_value (const gchar *namespace,
                      GITypeInfo *type,
                      GArgument  *value,
                      Xml        *file)
@@ -601,8 +765,7 @@ write_constant_value (const gchar *namespace,
 static void
 write_constant_info (const gchar    *namespace,
                     GIConstantInfo *info,
-                    Xml            *file,
-                    gint            indent)
+                    Xml            *file)
 {
   GITypeInfo *type;
   const gchar *name;
@@ -612,23 +775,22 @@ write_constant_info (const gchar    *namespace,
   name = g_base_info_get_name ((GIBaseInfo *)info);
   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
 
-  xml_printf (file, "%*s<constant name=\"%s\"", indent, "", name);
+  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, "\">\n");
-
-  xml_printf (file, "%*s<type name=\"", indent + 2, "");
+  xml_printf (file, "\"");
 
   write_type_info (namespace, type, file);
 
-  xml_printf (file, "\"/>\n");
+  write_attributes (file, (GIBaseInfo*) info);
+
+  xml_end_element (file, "constant");
 
-  xml_printf (file, "%*s</constant>\n", indent, "");
-  
   g_base_info_unref ((GIBaseInfo *)type);
 }
 
@@ -651,18 +813,18 @@ write_enum_info (const gchar *namespace,
   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
 
   if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
-    xml_printf (file, "    <enumeration ");
+    xml_start_element (file, "enumeration");
   else
-    xml_printf (file, "    <bitfield ");
-  xml_printf (file, "name=\"%s\"", name);
+    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\"");
-       
-  xml_printf (file, ">\n");
+
+  write_attributes (file, (GIBaseInfo*) info);
 
   for (i = 0; i < g_enum_info_get_n_values (info); i++)
     {
@@ -671,10 +833,7 @@ write_enum_info (const gchar *namespace,
       g_base_info_unref ((GIBaseInfo *)value);
     }
 
-  if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
-    xml_printf (file, "    </enumeration>\n");
-  else
-    xml_printf (file, "    </bitfield>\n");
+  xml_end_element_unchecked (file);
 }
 
 static void
@@ -690,11 +849,12 @@ write_signal_info (const gchar  *namespace,
   flags = g_signal_info_get_flags (info);
   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
 
-  xml_printf (file, "      <glib:signal name=\"%s\"", name);
+  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)
@@ -714,18 +874,19 @@ write_signal_info (const gchar  *namespace,
   if (flags & G_SIGNAL_NO_HOOKS)
     xml_printf (file, " no-hooks=\"1\"");
 
-  write_callable_info (namespace, (GICallableInfo*)info, file, 6);
+  write_callable_info (namespace, (GICallableInfo*)info, file);
 
-  xml_printf (file, "      </glib:signal>\n");
+  xml_end_element (file, "glib:signal");
 }
 
 static void
-write_vfunc_info (const gchar *namespace, 
+write_vfunc_info (const gchar *namespace,
                  GIVFuncInfo *info,
                  Xml         *file)
 {
   GIVFuncInfoFlags flags;
   const gchar *name;
+  GIFunctionInfo *invoker;
   gboolean deprecated;
   gint offset;
 
@@ -733,12 +894,14 @@ write_vfunc_info (const gchar *namespace,
   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_printf (file, "      <vfunc name=\"%s\"", name);
+  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\"");
 
@@ -746,12 +909,15 @@ write_vfunc_info (const gchar *namespace,
     xml_printf (file, " override=\"always\"");
   else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE)
     xml_printf (file, " override=\"never\"");
-    
+
   xml_printf (file, " offset=\"%d\"", offset);
 
-  write_callable_info (namespace, (GICallableInfo*)info, file, 6);
+  if (invoker)
+    xml_printf (file, " invoker=\"%s\"", g_base_info_get_name ((GIBaseInfo*)invoker));
+
+  write_callable_info (namespace, (GICallableInfo*)info, file);
 
-  xml_printf (file, "      </vfunc>\n");
+  xml_end_element (file, "virtual-method");
 }
 
 static void
@@ -768,43 +934,35 @@ write_property_info (const gchar    *namespace,
   flags = g_property_info_get_flags (info);
   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
 
-  xml_printf (file, "      <property name=\"%s\"", name);
+  xml_start_element (file, "property");
+  xml_printf (file, " name=\"%s\"", name);
 
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
-       
-  if (flags & G_PARAM_READABLE)
-    xml_printf (file, " readable=\"1\"");
-  else
-    xml_printf (file, " readable=\"0\"");
 
+  /* 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\"");
-  else
-    xml_printf (file, " writable=\"0\"");
 
   if (flags & G_PARAM_CONSTRUCT)
     xml_printf (file, " construct=\"1\"");
 
   if (flags & G_PARAM_CONSTRUCT_ONLY)
     xml_printf (file, " construct-only=\"1\"");
-    
-  type = g_property_info_get_type (info);
 
-  xml_printf (file, ">\n");
+  write_attributes (file, (GIBaseInfo*) info);
 
-  xml_printf (file, "        <type name=\"", name);
+  type = g_property_info_get_type (info);
 
   write_type_info (namespace, type, file);
 
-  xml_printf (file, "\"/>\n");
-  
-  xml_printf (file, "      </property>\n");
-
+  xml_end_element (file, "property");
 }
 
 static void
-write_object_info (const gchar  *namespace, 
+write_object_info (const gchar  *namespace,
                   GIObjectInfo *info,
                   Xml          *file)
 {
@@ -812,40 +970,52 @@ write_object_info (const gchar  *namespace,
   const gchar *type_name;
   const gchar *type_init;
   gboolean deprecated;
+  gboolean is_abstract;
   GIObjectInfo *pnode;
+  GIStructInfo *class_struct;
   gint i;
 
   name = g_base_info_get_name ((GIBaseInfo *)info);
   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
-  
+  is_abstract = g_object_info_get_abstract (info);
+
   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
-  xml_printf (file, "    <class name=\"%s\"", name);
+  xml_start_element (file, "class");
+  xml_printf (file, " name=\"%s\"", name);
 
   pnode = g_object_info_get_parent (info);
   if (pnode)
     {
-      xml_printf (file, " parent=\"");
-      write_type_name (namespace, (GIBaseInfo *)pnode, file);
-      xml_printf (file, "\""  );
+      write_type_name_attribute (namespace, (GIBaseInfo *)pnode, "parent", file);
       g_base_info_unref ((GIBaseInfo *)pnode);
     }
 
+  class_struct = g_object_info_get_class_struct (info);
+  if (class_struct)
+    {
+      write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file);
+      g_base_info_unref ((GIBaseInfo*)class_struct);
+    }
+
+  if (is_abstract)
+    xml_printf (file, " abstract=\"1\"");
+
   xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
 
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
-       
-  xml_printf (file, ">\n");
+
+  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_printf (file, "      <implements name=\"");
-         write_type_name (namespace, (GIBaseInfo*)imp, file);
-         xml_printf (file,"\" />\n");
+          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);
        }
     }
@@ -860,7 +1030,7 @@ write_object_info (const gchar  *namespace,
   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, 6);
+      write_function_info (namespace, function, file);
       g_base_info_unref ((GIBaseInfo *)function);
     }
 
@@ -877,7 +1047,7 @@ write_object_info (const gchar  *namespace,
       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);
@@ -888,11 +1058,11 @@ write_object_info (const gchar  *namespace,
   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, 6);
+      write_constant_info (namespace, constant, file);
       g_base_info_unref ((GIBaseInfo *)constant);
     }
-  
-  xml_printf (file, "    </class>\n");
+
+  xml_end_element (file, "class");
 }
 
 static void
@@ -903,6 +1073,7 @@ write_interface_info (const gchar     *namespace,
   const gchar *name;
   const gchar *type_name;
   const gchar *type_init;
+  GIStructInfo *class_struct;
   gboolean deprecated;
   gint i;
 
@@ -911,36 +1082,40 @@ write_interface_info (const gchar     *namespace,
 
   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
-  xml_printf (file, "    <interface name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"",
+  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\"");
-       
-  xml_printf (file, ">\n");
+
+  write_attributes (file, (GIBaseInfo*) info);
 
   if (g_interface_info_get_n_prerequisites (info) > 0)
     {
-      xml_printf (file, "      <requires>\n");
       for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++)
        {
          GIBaseInfo *req = g_interface_info_get_prerequisite (info, i);
-         
-         if (g_base_info_get_type (req) == GI_INFO_TYPE_INTERFACE)
-           xml_printf (file, "      <interface name=\"");
-         else
-           xml_printf (file, "      <object name=\"");
-         write_type_name (namespace, req, file);
-         xml_printf (file, "\" />\n");
+
+         xml_start_element (file, "prerequisite");
+         write_type_name_attribute (namespace, req, "name", file);
+
+          xml_end_element_unchecked (file);
          g_base_info_unref (req);
        }
-      xml_printf (file, "      </requires>\n");
     }
 
   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, 6);
+      write_function_info (namespace, function, file);
       g_base_info_unref ((GIBaseInfo *)function);
     }
 
@@ -957,7 +1132,7 @@ write_interface_info (const gchar     *namespace,
       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);
@@ -968,11 +1143,11 @@ write_interface_info (const gchar     *namespace,
   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, 6);
+      write_constant_info (namespace, constant, file);
       g_base_info_unref ((GIBaseInfo *)constant);
     }
-  
-  xml_printf (file, "    </interface>\n");
+
+  xml_end_element (file, "interface");
 }
 
 static void
@@ -982,21 +1157,21 @@ write_error_domain_info (const gchar       *namespace,
 {
   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_printf (file,
-            "    <errordomain name=\"%s\" get-quark=\"%s\" codes=\"",
-            name, quark);
-  write_type_name (namespace, enum_, file);
-  xml_printf (file, "\" />\n");
+  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, 
+write_union_info (const gchar *namespace,
+                 GIUnionInfo *info,
                  Xml         *file)
 {
   const gchar *name;
@@ -1004,22 +1179,28 @@ write_union_info (const gchar *namespace,
   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_printf (file, "    <union name=\"%s\"", name);
-  
+
+  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\"");
-       
-  xml_printf (file, ">\n");
+
+  size = g_union_info_get_size (info);
+  if (show_all && size >= 0)
+    xml_printf (file, " size=\"%d\"", size);
+
+  write_attributes (file, (GIBaseInfo*) info);
 
   if (g_union_info_is_discriminated (info))
     {
@@ -1028,10 +1209,11 @@ write_union_info (const gchar *namespace,
 
       offset = g_union_info_get_discriminator_offset (info);
       type = g_union_info_get_discriminator_type (info);
-      
-      xml_printf (file, "      <discriminator offset=\"%d\" type=\"", offset);
+
+      xml_start_element (file, "discriminator");
+      xml_printf (file, " offset=\"%d\" type=\"", offset);
       write_type_info (namespace, type, file);
-      xml_printf (file, "\" />\n");
+      xml_end_element (file, "discriminator");
       g_base_info_unref ((GIBaseInfo *)type);
     }
 
@@ -1048,11 +1230,11 @@ write_union_info (const gchar *namespace,
   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, 6);
+      write_function_info (namespace, function, file);
       g_base_info_unref ((GIBaseInfo *)function);
     }
 
-  xml_printf (file, "    </union>\n");
+  xml_end_element (file, "union");
 }
 
 static void
@@ -1060,7 +1242,6 @@ write_repository (const char   *namespace,
                  gboolean      needs_prefix)
 {
   FILE *ofile;
-  gchar *ns;
   gint i, j;
   char **dependencies;
   GIRepository *repository;
@@ -1073,32 +1254,33 @@ write_repository (const char   *namespace,
   else
     {
       gchar *filename;
-      
+
       if (needs_prefix)
-       filename = g_strdup_printf ("%s-%s", namespace, output);  
+       filename = g_strdup_printf ("%s-%s", namespace, output);
       else
        filename = g_strdup (output);
       ofile = g_fopen (filename, "w");
-      
+
       if (ofile == NULL)
        {
          g_fprintf (stderr, "failed to open '%s': %s\n",
                     filename, g_strerror (errno));
          g_free (filename);
-         
+
          return;
        }
-      
+
       g_free (filename);
     }
 
   xml = xml_open (ofile);
-  
+
   xml_printf (xml, "<?xml version=\"1.0\"?>\n");
-  xml_printf (xml, "<repository 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\">\n");
+             "            xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
 
   dependencies = g_irepository_get_dependencies (repository,
                                                 namespace);
@@ -1106,36 +1288,43 @@ write_repository (const char   *namespace,
     {
       for (i = 0; dependencies[i]; i++)
        {
-         xml_printf (xml, "  <include name=\"%s\"/>\n", dependencies[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, "  <namespace name=\"%s\" version=\"%s\" shared-library=\"%s\">\n",
-                    ns, version, shared_library);
-      else
-        xml_printf (xml, "  <namespace name=\"%s\" version=\"%s\">\n", ns, version);
-      
+        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, 4);
+             write_function_info (ns, (GIFunctionInfo *)info, xml);
              break;
-             
+
            case GI_INFO_TYPE_CALLBACK:
-             write_callback_info (ns, (GICallbackInfo *)info, xml, 4);
+             write_callback_info (ns, (GICallbackInfo *)info, xml);
              break;
 
            case GI_INFO_TYPE_STRUCT:
@@ -1151,9 +1340,9 @@ write_repository (const char   *namespace,
            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, 4);
+             write_constant_info (ns, (GIConstantInfo *)info, xml);
              break;
 
            case GI_INFO_TYPE_OBJECT:
@@ -1175,11 +1364,11 @@ write_repository (const char   *namespace,
          g_base_info_unref (info);
        }
 
-      xml_printf (xml, "  </namespace>\n");
+      xml_end_element (xml, "namespace");
     }
 
-  xml_printf (xml, "</repository>\n");
-      
+  xml_end_element (xml, "repository");
+
   xml_free (xml);
 }
 
@@ -1190,41 +1379,41 @@ load_typelib (const gchar  *filename,
 {
   guchar *typelib;
   gsize *typelib_size;
-  GModule *handle; 
+  GModule *handle;
 
   handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
   if (handle == NULL)
     {
-      g_printerr ("Could not load typelib from '%s': %s\n", 
+      g_printerr ("Could not load typelib from '%s': %s\n",
                  filename, g_module_error ());
       return NULL;
     }
 
   if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &typelib))
     {
-      g_printerr ("Could not load typelib from '%s': %s\n", 
+      g_printerr ("Could not load typelib from '%s': %s\n",
                  filename, g_module_error ());
       return NULL;
     }
-  
+
   if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &typelib_size))
     {
-      g_printerr ("Could not load typelib from '%s': %s\n", 
+      g_printerr ("Could not load typelib from '%s': %s\n",
                  filename, g_module_error ());
       return NULL;
     }
 
   *len = *typelib_size;
-  
+
   if (dlhandle)
     *dlhandle = handle;
 
   return typelib;
 }
 
-int 
+int
 main (int argc, char *argv[])
-{  
+{
   gboolean shlib = FALSE;
   gchar **input = NULL;
   GOptionContext *context;
@@ -1232,11 +1421,12 @@ main (int argc, char *argv[])
   gboolean needs_prefix;
   gint i;
   GTypelib *data;
-  GOptionEntry options[] = 
+  GOptionEntry options[] =
     {
       { "shlib", 0, 0, G_OPTION_ARG_NONE, &shlib, "handle typelib embedded in shlib", NULL },
-      { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" }, 
-      { "includedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &includedirs, "include directories in GIR search path", NULL }, 
+      { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" },
+      { "includedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &includedirs, "include directories in GIR search path", NULL },
+      { "all", 0, 0, G_OPTION_ARG_NONE, &show_all, "show all available information", NULL, },
       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL },
       { NULL, }
     };
@@ -1251,10 +1441,10 @@ main (int argc, char *argv[])
   g_option_context_add_main_entries (context, options, NULL);
   g_option_context_parse (context, &argc, &argv, &error);
 
-  if (!input) 
-    { 
-      g_fprintf (stderr, "no input files\n"); 
-      
+  if (!input)
+    {
+      g_fprintf (stderr, "no input files\n");
+
       return 1;
     }
 
@@ -1273,7 +1463,7 @@ main (int argc, char *argv[])
        {
          if (!g_file_get_contents (input[i], (gchar **)&typelib, &len, &error))
            {
-             g_fprintf (stderr, "failed to read '%s': %s\n", 
+             g_fprintf (stderr, "failed to read '%s': %s\n",
                         input[i], error->message);
              g_clear_error (&error);
              continue;
@@ -1284,7 +1474,7 @@ main (int argc, char *argv[])
          typelib = load_typelib (input[i], &dlhandle, &len);
          if (!typelib)
            {
-             g_fprintf (stderr, "failed to load typelib from '%s'\n", 
+             g_fprintf (stderr, "failed to load typelib from '%s'\n",
                         input[i]);
              continue;
            }
@@ -1311,7 +1501,7 @@ main (int argc, char *argv[])
          g_printerr ("failed to load typelib: %s\n", error->message);
          return 1;
        }
-       
+
       write_repository (namespace, needs_prefix);
 
       if (dlhandle)
@@ -1329,6 +1519,6 @@ main (int argc, char *argv[])
          break;
        }
     }
-      
+
   return 0;
 }