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