Add support for foreign structs
[gnome.gobject-introspection] / tools / generate.c
index 52c7064..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
@@ -32,6 +34,7 @@
 /* FIXME: Avoid global */
 static gchar *output = NULL;
 gchar **includedirs = NULL;
+static gboolean show_all = FALSE;
 
 typedef struct {
   FILE *file;
@@ -154,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)
@@ -188,27 +191,27 @@ write_type_name_attribute (const gchar *namespace,
 
 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)
     {
       xml_start_element (file, "type");
 
       xml_printf (file, " name=\"%s\"", is_pointer ? "any" : "none");
 
       xml_end_element (file, "type");
-    } 
+    }
   else if (G_TYPE_TAG_IS_BASIC (tag))
     {
       xml_start_element (file, "type");
@@ -217,17 +220,20 @@ write_type_info (const gchar *namespace,
     }
   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);
 
       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, " zero-terminated=\"1\"");
 
@@ -284,7 +290,7 @@ write_type_info (const gchar *namespace,
        }
       xml_end_element (file, "type");
     }
-  else if (tag == GI_TYPE_TAG_ERROR) 
+  else if (tag == GI_TYPE_TAG_ERROR)
     {
       gint n;
 
@@ -314,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,
@@ -330,7 +356,8 @@ 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);
@@ -351,7 +378,7 @@ write_field_info (const gchar *namespace,
   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);
 
@@ -364,13 +391,27 @@ write_field_info (const gchar *namespace,
       xml_printf (file, "\"");
     }
 
-  write_type_info (namespace, type, file);
+  if (show_all)
+    {
+      if (offset >= 0)
+        xml_printf (file, "offset=\"%d\"", offset);
+    }
+
+  interface = g_type_info_get_interface (type);
+  if (interface && g_base_info_get_type(interface) == GI_INFO_TYPE_CALLBACK)
+    write_callback_info (namespace, (GICallbackInfo *)interface, file);
+  else
+    write_type_info (namespace, type, file);
+
+  if (interface)
+    g_base_info_unref (interface);
+
   g_base_info_unref ((GIBaseInfo *)type);
 
   xml_end_element (file, "field");
 }
 
-static void 
+static void
 write_callable_info (const gchar    *namespace,
                     GICallableInfo *info,
                     Xml            *file)
@@ -378,34 +419,34 @@ write_callable_info (const gchar    *namespace,
   GITypeInfo *type;
   gint i;
 
+  write_attributes (file, (GIBaseInfo*) info);
+
   type = g_callable_info_get_return_type (info);
 
   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, " allow-none=\"1\"");
 
   write_type_info (namespace, type, file);
 
   xml_end_element (file, "return-value");
-       
+
   if (g_callable_info_get_n_args (info) <= 0)
     return;
 
@@ -413,25 +454,26 @@ write_callable_info (const gchar    *namespace,
   for (i = 0; i < g_callable_info_get_n_args (info); i++)
     {
       GIArgInfo *arg = g_callable_info_get_arg (info, i);
-      
+
       xml_start_element (file, "parameter");
       xml_printf (file, " name=\"%s\"",
                   g_base_info_get_name ((GIBaseInfo *) arg));
-      
+
       switch (g_arg_info_get_ownership_transfer (arg))
        {
        case GI_TRANSFER_NOTHING:
+         xml_printf (file, " transfer-ownership=\"none\"");
          break;
        case GI_TRANSFER_CONTAINER:
-         xml_printf (file, " transfer=\"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 ();
        }
-      
+
       switch (g_arg_info_get_direction (arg))
        {
        case GI_DIRECTION_IN:
@@ -443,19 +485,40 @@ write_callable_info (const gchar    *namespace,
          xml_printf (file, " direction=\"inout\"");
          break;
        }
-      
+
       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\"");
-      
+
+      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);
 
@@ -463,7 +526,7 @@ write_callable_info (const gchar    *namespace,
 
       g_base_info_unref ((GIBaseInfo *)arg);
     }
-  
+
   xml_end_element (file, "parameters");
   g_base_info_unref ((GIBaseInfo *)type);
 }
@@ -478,11 +541,13 @@ write_function_info (const gchar    *namespace,
   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";
@@ -490,19 +555,22 @@ write_function_info (const gchar    *namespace,
     tag = "method";
   else
     tag = "function";
-       
+
   xml_start_element (file, tag);
   xml_printf (file, " name=\"%s\" c:identifier=\"%s\"",
               name, symbol);
-       
+
   if (flags & GI_FUNCTION_IS_SETTER)
     xml_printf (file, " type=\"setter\"");
   else if (flags & GI_FUNCTION_IS_GETTER)
     xml_printf (file, " type=\"getter\"");
-         
+
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
 
+  if (throws)
+    xml_printf (file, " throws=\"1\"");
+
   write_callable_info (namespace, (GICallableInfo*)info, file);
   xml_end_element (file, tag);
 }
@@ -520,10 +588,10 @@ write_callback_info (const gchar    *namespace,
 
   xml_start_element (file, "callback");
   xml_printf (file, " name=\"%s\"", name);
-       
+
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
-       
+
   write_callable_info (namespace, (GICallableInfo*)info, file);
   xml_end_element (file, "callback");
 }
@@ -537,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);
@@ -545,7 +616,7 @@ 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_start_element (file, "glib:boxed");
@@ -556,13 +627,27 @@ write_struct_info (const gchar  *namespace,
       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)
     {
@@ -572,15 +657,15 @@ write_struct_info (const gchar  *namespace,
          write_field_info (namespace, field, NULL, file);
          g_base_info_unref ((GIBaseInfo *)field);
        }
-      
+
       for (i = 0; i < g_struct_info_get_n_methods (info); i++)
        {
          GIFunctionInfo *function = g_struct_info_get_method (info, i);
          write_function_info (namespace, function, file);
          g_base_info_unref ((GIBaseInfo *)function);
        }
-      
-    } 
+
+    }
 
   xml_end_element_unchecked (file);
 }
@@ -603,12 +688,14 @@ write_value_info (const gchar *namespace,
 
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
-  
+
+  write_attributes (file, (GIBaseInfo*) info);
+
   xml_end_element (file, "member");
 }
 
 static void
-write_constant_value (const gchar *namespace, 
+write_constant_value (const gchar *namespace,
                      GITypeInfo *type,
                      GArgument  *value,
                      Xml        *file)
@@ -700,8 +787,10 @@ write_constant_info (const gchar    *namespace,
 
   write_type_info (namespace, type, file);
 
+  write_attributes (file, (GIBaseInfo*) info);
+
   xml_end_element (file, "constant");
-  
+
   g_base_info_unref ((GIBaseInfo *)type);
 }
 
@@ -731,10 +820,11 @@ write_enum_info (const gchar *namespace,
 
   if (type_init)
     xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
-  
+
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
-       
+
+  write_attributes (file, (GIBaseInfo*) info);
 
   for (i = 0; i < g_enum_info_get_n_values (info); i++)
     {
@@ -764,7 +854,7 @@ write_signal_info (const gchar  *namespace,
 
   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)
@@ -790,12 +880,13 @@ write_signal_info (const gchar  *namespace,
 }
 
 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;
 
@@ -803,13 +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_start_element (file, "vfunc");
+  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\"");
 
@@ -817,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);
 
+  if (invoker)
+    xml_printf (file, " invoker=\"%s\"", g_base_info_get_name ((GIBaseInfo*)invoker));
+
   write_callable_info (namespace, (GICallableInfo*)info, file);
 
-  xml_end_element (file, "vfunc");
+  xml_end_element (file, "virtual-method");
 }
 
 static void
@@ -856,7 +951,9 @@ write_property_info (const gchar    *namespace,
 
   if (flags & G_PARAM_CONSTRUCT_ONLY)
     xml_printf (file, " construct-only=\"1\"");
-    
+
+  write_attributes (file, (GIBaseInfo*) info);
+
   type = g_property_info_get_type (info);
 
   write_type_info (namespace, type, file);
@@ -865,7 +962,7 @@ write_property_info (const gchar    *namespace,
 }
 
 static void
-write_object_info (const gchar  *namespace, 
+write_object_info (const gchar  *namespace,
                   GIObjectInfo *info,
                   Xml          *file)
 {
@@ -873,12 +970,15 @@ 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_start_element (file, "class");
@@ -891,11 +991,22 @@ write_object_info (const gchar  *namespace,
       g_base_info_unref ((GIBaseInfo *)pnode);
     }
 
+  class_struct = g_object_info_get_class_struct (info);
+  if (class_struct)
+    {
+      write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file);
+      g_base_info_unref ((GIBaseInfo*)class_struct);
+    }
+
+  if (is_abstract)
+    xml_printf (file, " abstract=\"1\"");
+
   xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
 
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
-       
+
+  write_attributes (file, (GIBaseInfo*) info);
 
   if (g_object_info_get_n_interfaces (info) > 0)
     {
@@ -936,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);
@@ -950,7 +1061,7 @@ write_object_info (const gchar  *namespace,
       write_constant_info (namespace, constant, file);
       g_base_info_unref ((GIBaseInfo *)constant);
     }
-  
+
   xml_end_element (file, "class");
 }
 
@@ -962,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;
 
@@ -974,26 +1086,30 @@ write_interface_info (const gchar     *namespace,
   xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"",
             name, type_name, type_init);
 
+  class_struct = g_interface_info_get_iface_struct (info);
+  if (class_struct)
+    {
+      write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file);
+      g_base_info_unref ((GIBaseInfo*)class_struct);
+    }
+
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
-       
+
+  write_attributes (file, (GIBaseInfo*) info);
 
   if (g_interface_info_get_n_prerequisites (info) > 0)
     {
-      xml_start_element (file, "requires");
       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_start_element (file, "interface");
-         else
-            xml_start_element (file, "object");
+
+         xml_start_element (file, "prerequisite");
          write_type_name_attribute (namespace, req, "name", file);
+
           xml_end_element_unchecked (file);
          g_base_info_unref (req);
        }
-      xml_end_element (file, "requires");
     }
 
   for (i = 0; i < g_interface_info_get_n_methods (info); i++)
@@ -1016,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);
@@ -1030,7 +1146,7 @@ write_interface_info (const gchar     *namespace,
       write_constant_info (namespace, constant, file);
       g_base_info_unref ((GIBaseInfo *)constant);
     }
-  
+
   xml_end_element (file, "interface");
 }
 
@@ -1041,7 +1157,7 @@ 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);
@@ -1054,8 +1170,8 @@ write_error_domain_info (const gchar       *namespace,
 }
 
 static void
-write_union_info (const gchar *namespace, 
-                 GIUnionInfo *info, 
+write_union_info (const gchar *namespace,
+                 GIUnionInfo *info,
                  Xml         *file)
 {
   const gchar *name;
@@ -1063,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_start_element (file, "union");
   xml_printf (file, " name=\"%s\"", name);
-  
+
   if (type_name)
     xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
-         
+
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
-       
+
+  size = g_union_info_get_size (info);
+  if (show_all && size >= 0)
+    xml_printf (file, " size=\"%d\"", size);
+
+  write_attributes (file, (GIBaseInfo*) info);
 
   if (g_union_info_is_discriminated (info))
     {
@@ -1087,7 +1209,7 @@ write_union_info (const gchar *namespace,
 
       offset = g_union_info_get_discriminator_offset (info);
       type = g_union_info_get_discriminator_type (info);
-      
+
       xml_start_element (file, "discriminator");
       xml_printf (file, " offset=\"%d\" type=\"", offset);
       write_type_info (namespace, type, file);
@@ -1132,27 +1254,27 @@ 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_start_element (xml, "repository");
   xml_printf (xml, " version=\"1.0\"\n"
@@ -1177,17 +1299,21 @@ write_repository (const char   *namespace,
   if (TRUE)
     {
       const gchar *shared_library;
+      const gchar *c_prefix;
       const char *ns = namespace;
       const char *version;
 
       version = g_irepository_get_version (repository, ns);
 
       shared_library = g_irepository_get_shared_library (repository, ns);
+      c_prefix = g_irepository_get_c_prefix (repository, ns);
       xml_start_element (xml, "namespace");
       xml_printf (xml, " name=\"%s\" version=\"%s\"", ns, version);
       if (shared_library)
         xml_printf (xml, " shared-library=\"%s\"", shared_library);
-      
+      if (c_prefix)
+        xml_printf (xml, " c:prefix=\"%s\"", c_prefix);
+
       for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++)
        {
          GIBaseInfo *info = g_irepository_get_info (repository, ns, j);
@@ -1196,7 +1322,7 @@ write_repository (const char   *namespace,
            case GI_INFO_TYPE_FUNCTION:
              write_function_info (ns, (GIFunctionInfo *)info, xml);
              break;
-             
+
            case GI_INFO_TYPE_CALLBACK:
              write_callback_info (ns, (GICallbackInfo *)info, xml);
              break;
@@ -1214,7 +1340,7 @@ 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);
              break;
@@ -1242,7 +1368,7 @@ write_repository (const char   *namespace,
     }
 
   xml_end_element (xml, "repository");
-      
+
   xml_free (xml);
 }
 
@@ -1253,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;
@@ -1295,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, }
     };
@@ -1314,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;
     }
 
@@ -1336,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;
@@ -1347,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;
            }
@@ -1374,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)
@@ -1392,6 +1519,6 @@ main (int argc, char *argv[])
          break;
        }
     }
-      
+
   return 0;
 }