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