a71f3654cf6e07ecec9b6b0f1d398fc3edd3fdc0
[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_field_info (const gchar *namespace,
344                   GIFieldInfo *info,
345                   GIConstantInfo *branch,
346                   Xml         *file)
347 {
348   const gchar *name;
349   GIFieldInfoFlags flags;
350   gint size;
351   gint offset;
352   GITypeInfo *type;
353   GArgument value; 
354
355   name = g_base_info_get_name ((GIBaseInfo *)info);
356   flags = g_field_info_get_flags (info);
357   size = g_field_info_get_size (info);
358   offset = g_field_info_get_offset (info);
359
360   xml_start_element (file, "field");
361   xml_printf (file, " name=\"%s\"", name);
362
363   /* Fields are assumed to be read-only
364    * (see also girwriter.py and girparser.c)
365    */
366   if (!(flags & GI_FIELD_IS_READABLE))
367     xml_printf (file, " readable=\"0\"");
368   if (flags & GI_FIELD_IS_WRITABLE)
369     xml_printf (file, " writable=\"1\"");
370
371   if (size)
372     xml_printf (file, " bits=\"%d\"", size);
373
374   write_attributes (file, (GIBaseInfo*) info);
375
376   type = g_field_info_get_type (info);
377
378   if (branch)
379     {
380       xml_printf (file, " branch=\"");
381       type = g_constant_info_get_type (branch);
382       g_constant_info_get_value (branch, &value);
383       write_constant_value (namespace, type, &value, file);
384       xml_printf (file, "\"");
385     }
386
387   if (show_all)
388     {
389       if (offset >= 0)
390         xml_printf (file, "offset=\"%d\"", offset);
391     }
392   
393   write_type_info (namespace, type, file);
394   g_base_info_unref ((GIBaseInfo *)type);
395
396   xml_end_element (file, "field");
397 }
398
399 static void 
400 write_callable_info (const gchar    *namespace,
401                      GICallableInfo *info,
402                      Xml            *file)
403 {
404   GITypeInfo *type;
405   gint i;
406
407   write_attributes (file, (GIBaseInfo*) info);
408
409   type = g_callable_info_get_return_type (info);
410
411   xml_start_element (file, "return-value");
412
413   switch (g_callable_info_get_caller_owns (info))
414     {
415     case GI_TRANSFER_NOTHING:
416       xml_printf (file, " transfer-ownership=\"none\"");
417       break;
418     case GI_TRANSFER_CONTAINER:
419       xml_printf (file, " transfer-ownership=\"container\"");
420       break;
421     case GI_TRANSFER_EVERYTHING:
422       xml_printf (file, " transfer-ownership=\"full\"");
423       break;
424     default:
425       g_assert_not_reached ();
426     }
427   
428   if (g_callable_info_may_return_null (info))
429     xml_printf (file, " allow-none=\"1\"");
430
431   write_type_info (namespace, type, file);
432
433   xml_end_element (file, "return-value");
434         
435   if (g_callable_info_get_n_args (info) <= 0)
436     return;
437
438   xml_start_element (file, "parameters");
439   for (i = 0; i < g_callable_info_get_n_args (info); i++)
440     {
441       GIArgInfo *arg = g_callable_info_get_arg (info, i);
442       
443       xml_start_element (file, "parameter");
444       xml_printf (file, " name=\"%s\"",
445                   g_base_info_get_name ((GIBaseInfo *) arg));
446       
447       switch (g_arg_info_get_ownership_transfer (arg))
448         {
449         case GI_TRANSFER_NOTHING:
450           xml_printf (file, " transfer-ownership=\"none\"");
451           break;
452         case GI_TRANSFER_CONTAINER:
453           xml_printf (file, " transfer-ownership=\"container\"");
454           break;
455         case GI_TRANSFER_EVERYTHING:
456           xml_printf (file, " transfer-ownership=\"full\"");
457           break;
458         default:
459           g_assert_not_reached ();
460         }
461       
462       switch (g_arg_info_get_direction (arg))
463         {
464         case GI_DIRECTION_IN:
465           break;
466         case GI_DIRECTION_OUT:
467           xml_printf (file, " direction=\"out\"");
468           break;
469         case GI_DIRECTION_INOUT:
470           xml_printf (file, " direction=\"inout\"");
471           break;
472         }
473       
474       if (g_arg_info_may_be_null (arg))
475         xml_printf (file, " allow-none=\"1\"");
476       
477       if (g_arg_info_is_dipper (arg))
478         xml_printf (file, " dipper=\"1\"");
479       
480       if (g_arg_info_is_return_value (arg))
481         xml_printf (file, " retval=\"1\"");
482       
483       if (g_arg_info_is_optional (arg))
484         xml_printf (file, " optional=\"1\"");
485
486       switch (g_arg_info_get_scope (arg))
487         {
488         case GI_SCOPE_TYPE_INVALID:
489           break;
490         case GI_SCOPE_TYPE_CALL:
491           xml_printf (file, " scope=\"call\"");
492           break;
493         case GI_SCOPE_TYPE_ASYNC:
494           xml_printf (file, " scope=\"async\"");
495           break;
496         case GI_SCOPE_TYPE_NOTIFIED:
497           xml_printf (file, " scope=\"notified\"");
498           break;
499         }
500       
501       if (g_arg_info_get_closure (arg) >= 0)
502         xml_printf (file, " closure=\"%d\"", g_arg_info_get_closure (arg));
503       
504       if (g_arg_info_get_destroy (arg) >= 0)
505         xml_printf (file, " destroy=\"%d\"", g_arg_info_get_destroy (arg));
506       
507       type = g_arg_info_get_type (arg);
508       write_type_info (namespace, type, file);
509
510       xml_end_element (file, "parameter");
511
512       g_base_info_unref ((GIBaseInfo *)arg);
513     }
514   
515   xml_end_element (file, "parameters");
516   g_base_info_unref ((GIBaseInfo *)type);
517 }
518
519 static void
520 write_function_info (const gchar    *namespace,
521                      GIFunctionInfo *info,
522                      Xml            *file)
523 {
524   GIFunctionInfoFlags flags;
525   const gchar *tag;
526   const gchar *name;
527   const gchar *symbol;
528   gboolean deprecated;
529   gboolean throws;
530
531   flags = g_function_info_get_flags (info);
532   name = g_base_info_get_name ((GIBaseInfo *)info);
533   symbol = g_function_info_get_symbol (info);
534   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
535   throws = flags & GI_FUNCTION_THROWS;
536
537   if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
538     tag = "constructor";
539   else if (flags & GI_FUNCTION_IS_METHOD)
540     tag = "method";
541   else
542     tag = "function";
543         
544   xml_start_element (file, tag);
545   xml_printf (file, " name=\"%s\" c:identifier=\"%s\"",
546               name, symbol);
547         
548   if (flags & GI_FUNCTION_IS_SETTER)
549     xml_printf (file, " type=\"setter\"");
550   else if (flags & GI_FUNCTION_IS_GETTER)
551     xml_printf (file, " type=\"getter\"");
552           
553   if (deprecated)
554     xml_printf (file, " deprecated=\"1\"");
555
556   if (throws)
557     xml_printf (file, " throws=\"1\"");
558
559   write_callable_info (namespace, (GICallableInfo*)info, file);
560   xml_end_element (file, tag);
561 }
562
563 static void
564 write_callback_info (const gchar    *namespace,
565                      GICallbackInfo *info,
566                      Xml            *file)
567 {
568   const gchar *name;
569   gboolean deprecated;
570
571   name = g_base_info_get_name ((GIBaseInfo *)info);
572   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
573
574   xml_start_element (file, "callback");
575   xml_printf (file, " name=\"%s\"", name);
576         
577   if (deprecated)
578     xml_printf (file, " deprecated=\"1\"");
579         
580   write_callable_info (namespace, (GICallableInfo*)info, file);
581   xml_end_element (file, "callback");
582 }
583
584 static void
585 write_struct_info (const gchar  *namespace,
586                    GIStructInfo *info,
587                    Xml          *file)
588 {
589   const gchar *name;
590   const gchar *type_name;
591   const gchar *type_init;
592   gboolean deprecated;
593   gboolean is_gtype_struct;
594   gint i;
595   gint size;
596   int n_elts;
597
598   name = g_base_info_get_name ((GIBaseInfo *)info);
599   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
600
601   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
602   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
603   
604   if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED)
605     {
606       xml_start_element (file, "glib:boxed");
607       xml_printf (file, " glib:name=\"%s\"", name);
608     }
609   else
610     {
611       xml_start_element (file, "record");
612       xml_printf (file, " name=\"%s\"", name);
613     }
614   
615   if (type_name != NULL)
616     xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
617           
618   if (deprecated)
619     xml_printf (file, " deprecated=\"1\"");
620   
621   is_gtype_struct = g_struct_info_is_gtype_struct (info);
622   if (is_gtype_struct)
623     xml_printf (file, " glib:is-gtype-struct=\"1\"");
624
625   write_attributes (file, (GIBaseInfo*) info);
626         
627   size = g_struct_info_get_size (info);
628   if (show_all && size >= 0)
629     xml_printf (file, " size=\"%d\"", size);
630
631   n_elts = g_struct_info_get_n_fields (info) + g_struct_info_get_n_methods (info);
632   if (n_elts > 0)
633     {
634       for (i = 0; i < g_struct_info_get_n_fields (info); i++)
635         {
636           GIFieldInfo *field = g_struct_info_get_field (info, i);
637           write_field_info (namespace, field, NULL, file);
638           g_base_info_unref ((GIBaseInfo *)field);
639         }
640       
641       for (i = 0; i < g_struct_info_get_n_methods (info); i++)
642         {
643           GIFunctionInfo *function = g_struct_info_get_method (info, i);
644           write_function_info (namespace, function, file);
645           g_base_info_unref ((GIBaseInfo *)function);
646         }
647       
648     } 
649
650   xml_end_element_unchecked (file);
651 }
652
653 static void
654 write_value_info (const gchar *namespace,
655                   GIValueInfo *info,
656                   Xml         *file)
657 {
658   const gchar *name;
659   glong value;
660   gboolean deprecated;
661
662   name = g_base_info_get_name ((GIBaseInfo *)info);
663   value = g_value_info_get_value (info);
664   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
665
666   xml_start_element (file, "member");
667   xml_printf (file, " name=\"%s\" value=\"%ld\"", name, value);
668
669   if (deprecated)
670     xml_printf (file, " deprecated=\"1\"");
671   
672   write_attributes (file, (GIBaseInfo*) info);
673
674   xml_end_element (file, "member");
675 }
676
677 static void
678 write_constant_value (const gchar *namespace, 
679                       GITypeInfo *type,
680                       GArgument  *value,
681                       Xml        *file)
682 {
683   switch (g_type_info_get_tag (type))
684     {
685     case GI_TYPE_TAG_BOOLEAN:
686       xml_printf (file, "%d", value->v_boolean);
687       break;
688     case GI_TYPE_TAG_INT8:
689       xml_printf (file, "%d", value->v_int8);
690       break;
691     case GI_TYPE_TAG_UINT8:
692       xml_printf (file, "%d", value->v_uint8);
693       break;
694     case GI_TYPE_TAG_INT16:
695       xml_printf (file, "%" G_GINT16_FORMAT, value->v_int16);
696       break;
697     case GI_TYPE_TAG_UINT16:
698       xml_printf (file, "%" G_GUINT16_FORMAT, value->v_uint16);
699       break;
700     case GI_TYPE_TAG_INT32:
701       xml_printf (file, "%" G_GINT32_FORMAT, value->v_int32);
702       break;
703     case GI_TYPE_TAG_UINT32:
704       xml_printf (file, "%" G_GUINT32_FORMAT, value->v_uint32);
705       break;
706     case GI_TYPE_TAG_INT64:
707       xml_printf (file, "%" G_GINT64_FORMAT, value->v_int64);
708       break;
709     case GI_TYPE_TAG_UINT64:
710       xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64);
711       break;
712     case GI_TYPE_TAG_INT:
713       xml_printf (file, "%d", value->v_int);
714       break;
715     case GI_TYPE_TAG_UINT:
716       xml_printf (file, "%d", value->v_uint);
717       break;
718     case GI_TYPE_TAG_LONG:
719       xml_printf (file, "%ld", value->v_long);
720       break;
721     case GI_TYPE_TAG_ULONG:
722       xml_printf (file, "%ld", value->v_ulong);
723       break;
724     case GI_TYPE_TAG_SSIZE:
725       xml_printf (file, "%zd", value->v_ssize);
726       break;
727     case GI_TYPE_TAG_SIZE:
728       xml_printf (file, "%zd", value->v_size);
729       break;
730     case GI_TYPE_TAG_FLOAT:
731       xml_printf (file, "%f", value->v_float);
732       break;
733     case GI_TYPE_TAG_DOUBLE:
734       xml_printf (file, "%f", value->v_double);
735       break;
736     case GI_TYPE_TAG_UTF8:
737     case GI_TYPE_TAG_FILENAME:
738       xml_printf (file, "%s", value->v_string);
739       break;
740     default:
741       g_assert_not_reached ();
742     }
743 }
744
745 static void
746 write_constant_info (const gchar    *namespace,
747                      GIConstantInfo *info,
748                      Xml            *file)
749 {
750   GITypeInfo *type;
751   const gchar *name;
752   gboolean deprecated;
753   GArgument value;
754
755   name = g_base_info_get_name ((GIBaseInfo *)info);
756   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
757
758   xml_start_element (file, "constant");
759   xml_printf (file, " name=\"%s\"", name);
760
761   type = g_constant_info_get_type (info);
762   xml_printf (file, " value=\"");
763
764   g_constant_info_get_value (info, &value);
765   write_constant_value (namespace, type, &value, file);
766   xml_printf (file, "\"");
767
768   write_type_info (namespace, type, file);
769
770   write_attributes (file, (GIBaseInfo*) info);
771
772   xml_end_element (file, "constant");
773   
774   g_base_info_unref ((GIBaseInfo *)type);
775 }
776
777
778 static void
779 write_enum_info (const gchar *namespace,
780                  GIEnumInfo *info,
781                  Xml         *file)
782 {
783   const gchar *name;
784   const gchar *type_name;
785   const gchar *type_init;
786   gboolean deprecated;
787   gint i;
788
789   name = g_base_info_get_name ((GIBaseInfo *)info);
790   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
791
792   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
793   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
794
795   if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
796     xml_start_element (file, "enumeration");
797   else
798     xml_start_element (file, "bitfield");
799   xml_printf (file, " name=\"%s\"", name);
800
801   if (type_init)
802     xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
803   
804   if (deprecated)
805     xml_printf (file, " deprecated=\"1\"");
806
807   write_attributes (file, (GIBaseInfo*) info);
808
809   for (i = 0; i < g_enum_info_get_n_values (info); i++)
810     {
811       GIValueInfo *value = g_enum_info_get_value (info, i);
812       write_value_info (namespace, value, file);
813       g_base_info_unref ((GIBaseInfo *)value);
814     }
815
816   xml_end_element_unchecked (file);
817 }
818
819 static void
820 write_signal_info (const gchar  *namespace,
821                    GISignalInfo *info,
822                    Xml          *file)
823 {
824   GSignalFlags flags;
825   const gchar *name;
826   gboolean deprecated;
827
828   name = g_base_info_get_name ((GIBaseInfo *)info);
829   flags = g_signal_info_get_flags (info);
830   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
831
832   xml_start_element (file, "glib:signal");
833   xml_printf (file, " name=\"%s\"", name);
834
835   if (deprecated)
836     xml_printf (file, " deprecated=\"1\"");
837         
838   if (flags & G_SIGNAL_RUN_FIRST)
839     xml_printf (file, " when=\"FIRST\"");
840   else if (flags & G_SIGNAL_RUN_LAST)
841     xml_printf (file, " when=\"LAST\"");
842   else if (flags & G_SIGNAL_RUN_CLEANUP)
843     xml_printf (file, " when=\"CLEANUP\"");
844
845   if (flags & G_SIGNAL_NO_RECURSE)
846     xml_printf (file, " no-recurse=\"1\"");
847
848   if (flags & G_SIGNAL_DETAILED)
849     xml_printf (file, " detailed=\"1\"");
850
851   if (flags & G_SIGNAL_ACTION)
852     xml_printf (file, " action=\"1\"");
853
854   if (flags & G_SIGNAL_NO_HOOKS)
855     xml_printf (file, " no-hooks=\"1\"");
856
857   write_callable_info (namespace, (GICallableInfo*)info, file);
858
859   xml_end_element (file, "glib:signal");
860 }
861
862 static void
863 write_vfunc_info (const gchar *namespace, 
864                   GIVFuncInfo *info,
865                   Xml         *file)
866 {
867   GIVFuncInfoFlags flags;
868   const gchar *name;
869   GIFunctionInfo *invoker;
870   gboolean deprecated;
871   gint offset;
872
873   name = g_base_info_get_name ((GIBaseInfo *)info);
874   flags = g_vfunc_info_get_flags (info);
875   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
876   offset = g_vfunc_info_get_offset (info);
877   invoker = g_vfunc_info_get_invoker (info);
878
879   xml_start_element (file, "virtual-method");
880   xml_printf (file, " name=\"%s\"", name);
881
882   if (deprecated)
883     xml_printf (file, " deprecated=\"1\"");
884         
885   if (flags & GI_VFUNC_MUST_CHAIN_UP)
886     xml_printf (file, " must-chain-up=\"1\"");
887
888   if (flags & GI_VFUNC_MUST_OVERRIDE)
889     xml_printf (file, " override=\"always\"");
890   else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE)
891     xml_printf (file, " override=\"never\"");
892     
893   xml_printf (file, " offset=\"%d\"", offset);
894
895   if (invoker)
896     xml_printf (file, " invoker=\"%s\"", g_base_info_get_name ((GIBaseInfo*)invoker));
897
898   write_callable_info (namespace, (GICallableInfo*)info, file);
899
900   xml_end_element (file, "virtual-method");
901 }
902
903 static void
904 write_property_info (const gchar    *namespace,
905                      GIPropertyInfo *info,
906                      Xml            *file)
907 {
908   GParamFlags flags;
909   const gchar *name;
910   gboolean deprecated;
911   GITypeInfo *type;
912
913   name = g_base_info_get_name ((GIBaseInfo *)info);
914   flags = g_property_info_get_flags (info);
915   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
916
917   xml_start_element (file, "property");
918   xml_printf (file, " name=\"%s\"", name);
919
920   if (deprecated)
921     xml_printf (file, " deprecated=\"1\"");
922
923   /* Properties are assumed to be read-only (see also girwriter.py) */
924   if (!(flags & G_PARAM_READABLE))
925     xml_printf (file, " readable=\"0\"");
926   if (flags & G_PARAM_WRITABLE)
927     xml_printf (file, " writable=\"1\"");
928
929   if (flags & G_PARAM_CONSTRUCT)
930     xml_printf (file, " construct=\"1\"");
931
932   if (flags & G_PARAM_CONSTRUCT_ONLY)
933     xml_printf (file, " construct-only=\"1\"");
934
935   write_attributes (file, (GIBaseInfo*) info);
936
937   type = g_property_info_get_type (info);
938
939   write_type_info (namespace, type, file);
940
941   xml_end_element (file, "property");
942 }
943
944 static void
945 write_object_info (const gchar  *namespace, 
946                    GIObjectInfo *info,
947                    Xml          *file)
948 {
949   const gchar *name;
950   const gchar *type_name;
951   const gchar *type_init;
952   gboolean deprecated;
953   gboolean is_abstract;
954   GIObjectInfo *pnode;
955   GIStructInfo *class_struct;
956   gint i;
957
958   name = g_base_info_get_name ((GIBaseInfo *)info);
959   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
960   is_abstract = g_object_info_get_abstract (info);
961   
962   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
963   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
964   xml_start_element (file, "class");
965   xml_printf (file, " name=\"%s\"", name);
966
967   pnode = g_object_info_get_parent (info);
968   if (pnode)
969     {
970       write_type_name_attribute (namespace, (GIBaseInfo *)pnode, "parent", file);
971       g_base_info_unref ((GIBaseInfo *)pnode);
972     }
973   
974   class_struct = g_object_info_get_class_struct (info);
975   if (class_struct)
976     {
977       write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file);
978       g_base_info_unref ((GIBaseInfo*)class_struct);
979     }
980
981   if (is_abstract)
982     xml_printf (file, " abstract=\"1\"");
983
984   xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
985
986   if (deprecated)
987     xml_printf (file, " deprecated=\"1\"");
988
989   write_attributes (file, (GIBaseInfo*) info);
990
991   if (g_object_info_get_n_interfaces (info) > 0)
992     {
993       for (i = 0; i < g_object_info_get_n_interfaces (info); i++)
994         {
995           GIInterfaceInfo *imp = g_object_info_get_interface (info, i);
996           xml_start_element (file, "implements");
997           write_type_name_attribute (namespace, (GIBaseInfo *)imp, "name", file);
998           xml_end_element (file, "implements");
999           g_base_info_unref ((GIBaseInfo*)imp);
1000         }
1001     }
1002
1003   for (i = 0; i < g_object_info_get_n_fields (info); i++)
1004     {
1005       GIFieldInfo *field = g_object_info_get_field (info, i);
1006       write_field_info (namespace, field, NULL, file);
1007       g_base_info_unref ((GIBaseInfo *)field);
1008     }
1009
1010   for (i = 0; i < g_object_info_get_n_methods (info); i++)
1011     {
1012       GIFunctionInfo *function = g_object_info_get_method (info, i);
1013       write_function_info (namespace, function, file);
1014       g_base_info_unref ((GIBaseInfo *)function);
1015     }
1016
1017   for (i = 0; i < g_object_info_get_n_properties (info); i++)
1018     {
1019       GIPropertyInfo *prop = g_object_info_get_property (info, i);
1020       write_property_info (namespace, prop, file);
1021       g_base_info_unref ((GIBaseInfo *)prop);
1022     }
1023
1024   for (i = 0; i < g_object_info_get_n_signals (info); i++)
1025     {
1026       GISignalInfo *signal = g_object_info_get_signal (info, i);
1027       write_signal_info (namespace, signal, file);
1028       g_base_info_unref ((GIBaseInfo *)signal);
1029     }
1030   
1031   for (i = 0; i < g_object_info_get_n_vfuncs (info); i++)
1032     {
1033       GIVFuncInfo *vfunc = g_object_info_get_vfunc (info, i);
1034       write_vfunc_info (namespace, vfunc, file);
1035       g_base_info_unref ((GIBaseInfo *)vfunc);
1036     }
1037
1038   for (i = 0; i < g_object_info_get_n_constants (info); i++)
1039     {
1040       GIConstantInfo *constant = g_object_info_get_constant (info, i);
1041       write_constant_info (namespace, constant, file);
1042       g_base_info_unref ((GIBaseInfo *)constant);
1043     }
1044   
1045   xml_end_element (file, "class");
1046 }
1047
1048 static void
1049 write_interface_info (const gchar     *namespace,
1050                       GIInterfaceInfo *info,
1051                       Xml             *file)
1052 {
1053   const gchar *name;
1054   const gchar *type_name;
1055   const gchar *type_init;
1056   GIStructInfo *class_struct;
1057   gboolean deprecated;
1058   gint i;
1059
1060   name = g_base_info_get_name ((GIBaseInfo *)info);
1061   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
1062
1063   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
1064   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
1065   xml_start_element (file, "interface");
1066   xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"",
1067              name, type_name, type_init);
1068
1069   class_struct = g_interface_info_get_iface_struct (info);
1070   if (class_struct)
1071     {
1072       write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file);
1073       g_base_info_unref ((GIBaseInfo*)class_struct);
1074     }
1075
1076   if (deprecated)
1077     xml_printf (file, " deprecated=\"1\"");
1078
1079   write_attributes (file, (GIBaseInfo*) info);
1080
1081   if (g_interface_info_get_n_prerequisites (info) > 0)
1082     {
1083       for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++)
1084         {
1085           GIBaseInfo *req = g_interface_info_get_prerequisite (info, i);
1086
1087           xml_start_element (file, "prerequisite");
1088           write_type_name_attribute (namespace, req, "name", file);
1089
1090           xml_end_element_unchecked (file);
1091           g_base_info_unref (req);
1092         }
1093     }
1094
1095   for (i = 0; i < g_interface_info_get_n_methods (info); i++)
1096     {
1097       GIFunctionInfo *function = g_interface_info_get_method (info, i);
1098       write_function_info (namespace, function, file);
1099       g_base_info_unref ((GIBaseInfo *)function);
1100     }
1101
1102   for (i = 0; i < g_interface_info_get_n_properties (info); i++)
1103     {
1104       GIPropertyInfo *prop = g_interface_info_get_property (info, i);
1105       write_property_info (namespace, prop, file);
1106       g_base_info_unref ((GIBaseInfo *)prop);
1107     }
1108
1109   for (i = 0; i < g_interface_info_get_n_signals (info); i++)
1110     {
1111       GISignalInfo *signal = g_interface_info_get_signal (info, i);
1112       write_signal_info (namespace, signal, file);
1113       g_base_info_unref ((GIBaseInfo *)signal);
1114     }
1115   
1116   for (i = 0; i < g_interface_info_get_n_vfuncs (info); i++)
1117     {
1118       GIVFuncInfo *vfunc = g_interface_info_get_vfunc (info, i);
1119       write_vfunc_info (namespace, vfunc, file);
1120       g_base_info_unref ((GIBaseInfo *)vfunc);
1121     }
1122
1123   for (i = 0; i < g_interface_info_get_n_constants (info); i++)
1124     {
1125       GIConstantInfo *constant = g_interface_info_get_constant (info, i);
1126       write_constant_info (namespace, constant, file);
1127       g_base_info_unref ((GIBaseInfo *)constant);
1128     }
1129   
1130   xml_end_element (file, "interface");
1131 }
1132
1133 static void
1134 write_error_domain_info (const gchar       *namespace,
1135                          GIErrorDomainInfo *info,
1136                          Xml               *file)
1137 {
1138   GIBaseInfo *enum_;
1139   const gchar *name, *quark;
1140   
1141   name = g_base_info_get_name ((GIBaseInfo *)info);
1142   quark = g_error_domain_info_get_quark (info);
1143   enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info);
1144   xml_start_element (file, "errordomain");
1145   xml_printf (file, " name=\"%s\" get-quark=\"%s\"",
1146               name, quark);
1147   write_type_name_attribute (namespace, enum_, "codes", file);
1148   xml_end_element (file, "errordomain");
1149   g_base_info_unref (enum_);
1150 }
1151
1152 static void
1153 write_union_info (const gchar *namespace, 
1154                   GIUnionInfo *info, 
1155                   Xml         *file)
1156 {
1157   const gchar *name;
1158   const gchar *type_name;
1159   const gchar *type_init;
1160   gboolean deprecated;
1161   gint i;
1162   gint size;
1163
1164   name = g_base_info_get_name ((GIBaseInfo *)info);
1165   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
1166
1167   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
1168   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
1169   
1170   xml_start_element (file, "union");
1171   xml_printf (file, " name=\"%s\"", name);
1172   
1173   if (type_name)
1174     xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
1175           
1176   if (deprecated)
1177     xml_printf (file, " deprecated=\"1\"");
1178
1179   size = g_union_info_get_size (info);
1180   if (show_all && size >= 0)
1181     xml_printf (file, " size=\"%d\"", size);
1182
1183   write_attributes (file, (GIBaseInfo*) info);
1184
1185   if (g_union_info_is_discriminated (info))
1186     {
1187       gint offset;
1188       GITypeInfo *type;
1189
1190       offset = g_union_info_get_discriminator_offset (info);
1191       type = g_union_info_get_discriminator_type (info);
1192       
1193       xml_start_element (file, "discriminator");
1194       xml_printf (file, " offset=\"%d\" type=\"", offset);
1195       write_type_info (namespace, type, file);
1196       xml_end_element (file, "discriminator");
1197       g_base_info_unref ((GIBaseInfo *)type);
1198     }
1199
1200   for (i = 0; i < g_union_info_get_n_fields (info); i++)
1201     {
1202       GIFieldInfo *field = g_union_info_get_field (info, i);
1203       GIConstantInfo *constant = g_union_info_get_discriminator (info, i);
1204       write_field_info (namespace, field, constant, file);
1205       g_base_info_unref ((GIBaseInfo *)field);
1206       if (constant)
1207         g_base_info_unref ((GIBaseInfo *)constant);
1208     }
1209
1210   for (i = 0; i < g_union_info_get_n_methods (info); i++)
1211     {
1212       GIFunctionInfo *function = g_union_info_get_method (info, i);
1213       write_function_info (namespace, function, file);
1214       g_base_info_unref ((GIBaseInfo *)function);
1215     }
1216
1217   xml_end_element (file, "union");
1218 }
1219
1220 static void
1221 write_repository (const char   *namespace,
1222                   gboolean      needs_prefix)
1223 {
1224   FILE *ofile;
1225   gint i, j;
1226   char **dependencies;
1227   GIRepository *repository;
1228   Xml *xml;
1229
1230   repository = g_irepository_get_default ();
1231
1232   if (output == NULL)
1233     ofile = stdout;
1234   else
1235     {
1236       gchar *filename;
1237       
1238       if (needs_prefix)
1239         filename = g_strdup_printf ("%s-%s", namespace, output);  
1240       else
1241         filename = g_strdup (output);
1242       ofile = g_fopen (filename, "w");
1243       
1244       if (ofile == NULL)
1245         {
1246           g_fprintf (stderr, "failed to open '%s': %s\n",
1247                      filename, g_strerror (errno));
1248           g_free (filename);
1249           
1250           return;
1251         }
1252       
1253       g_free (filename);
1254     }
1255
1256   xml = xml_open (ofile);
1257   
1258   xml_printf (xml, "<?xml version=\"1.0\"?>\n");
1259   xml_start_element (xml, "repository");
1260   xml_printf (xml, " version=\"1.0\"\n"
1261               "            xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n"
1262               "            xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n"
1263               "            xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
1264
1265   dependencies = g_irepository_get_dependencies (repository,
1266                                                  namespace);
1267   if (dependencies != NULL)
1268     {
1269       for (i = 0; dependencies[i]; i++)
1270         {
1271           char **parts = g_strsplit (dependencies[i], "-", 2);
1272           xml_start_element (xml, "include");
1273           xml_printf (xml, " name=\"%s\" version=\"%s\"", parts[0], parts[1]);
1274           xml_end_element (xml, "include");
1275           g_strfreev (parts);
1276         }
1277     }
1278
1279   if (TRUE)
1280     {
1281       const gchar *shared_library;
1282       const gchar *c_prefix;
1283       const char *ns = namespace;
1284       const char *version;
1285
1286       version = g_irepository_get_version (repository, ns);
1287
1288       shared_library = g_irepository_get_shared_library (repository, ns);
1289       c_prefix = g_irepository_get_c_prefix (repository, ns);
1290       xml_start_element (xml, "namespace");
1291       xml_printf (xml, " name=\"%s\" version=\"%s\"", ns, version);
1292       if (shared_library)
1293         xml_printf (xml, " shared-library=\"%s\"", shared_library);
1294       if (c_prefix)
1295         xml_printf (xml, " c:prefix=\"%s\"", c_prefix);
1296       
1297       for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++)
1298         {
1299           GIBaseInfo *info = g_irepository_get_info (repository, ns, j);
1300           switch (g_base_info_get_type (info))
1301             {
1302             case GI_INFO_TYPE_FUNCTION:
1303               write_function_info (ns, (GIFunctionInfo *)info, xml);
1304               break;
1305               
1306             case GI_INFO_TYPE_CALLBACK:
1307               write_callback_info (ns, (GICallbackInfo *)info, xml);
1308               break;
1309
1310             case GI_INFO_TYPE_STRUCT:
1311             case GI_INFO_TYPE_BOXED:
1312               write_struct_info (ns, (GIStructInfo *)info, xml);
1313               break;
1314
1315             case GI_INFO_TYPE_UNION:
1316               write_union_info (ns, (GIUnionInfo *)info, xml);
1317               break;
1318
1319             case GI_INFO_TYPE_ENUM:
1320             case GI_INFO_TYPE_FLAGS:
1321               write_enum_info (ns, (GIEnumInfo *)info, xml);
1322               break;
1323               
1324             case GI_INFO_TYPE_CONSTANT:
1325               write_constant_info (ns, (GIConstantInfo *)info, xml);
1326               break;
1327
1328             case GI_INFO_TYPE_OBJECT:
1329               write_object_info (ns, (GIObjectInfo *)info, xml);
1330               break;
1331
1332             case GI_INFO_TYPE_INTERFACE:
1333               write_interface_info (ns, (GIInterfaceInfo *)info, xml);
1334               break;
1335
1336             case GI_INFO_TYPE_ERROR_DOMAIN:
1337               write_error_domain_info (ns, (GIErrorDomainInfo *)info, xml);
1338               break;
1339
1340             default:
1341               g_error ("unknown info type %d\n", g_base_info_get_type (info));
1342             }
1343
1344           g_base_info_unref (info);
1345         }
1346
1347       xml_end_element (xml, "namespace");
1348     }
1349
1350   xml_end_element (xml, "repository");
1351       
1352   xml_free (xml);
1353 }
1354
1355 static const guchar *
1356 load_typelib (const gchar  *filename,
1357                GModule     **dlhandle,
1358                gsize        *len)
1359 {
1360   guchar *typelib;
1361   gsize *typelib_size;
1362   GModule *handle; 
1363
1364   handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
1365   if (handle == NULL)
1366     {
1367       g_printerr ("Could not load typelib from '%s': %s\n", 
1368                   filename, g_module_error ());
1369       return NULL;
1370     }
1371
1372   if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &typelib))
1373     {
1374       g_printerr ("Could not load typelib from '%s': %s\n", 
1375                   filename, g_module_error ());
1376       return NULL;
1377     }
1378   
1379   if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &typelib_size))
1380     {
1381       g_printerr ("Could not load typelib from '%s': %s\n", 
1382                   filename, g_module_error ());
1383       return NULL;
1384     }
1385
1386   *len = *typelib_size;
1387   
1388   if (dlhandle)
1389     *dlhandle = handle;
1390
1391   return typelib;
1392 }
1393
1394 int 
1395 main (int argc, char *argv[])
1396 {  
1397   gboolean shlib = FALSE;
1398   gchar **input = NULL;
1399   GOptionContext *context;
1400   GError *error = NULL;
1401   gboolean needs_prefix;
1402   gint i;
1403   GTypelib *data;
1404   GOptionEntry options[] = 
1405     {
1406       { "shlib", 0, 0, G_OPTION_ARG_NONE, &shlib, "handle typelib embedded in shlib", NULL },
1407       { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" }, 
1408       { "includedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &includedirs, "include directories in GIR search path", NULL },
1409       { "all", 0, 0, G_OPTION_ARG_NONE, &show_all, "show all available information", NULL, },
1410       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL },
1411       { NULL, }
1412     };
1413
1414   g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
1415
1416   g_type_init ();
1417
1418   g_typelib_check_sanity ();
1419
1420   context = g_option_context_new ("");
1421   g_option_context_add_main_entries (context, options, NULL);
1422   g_option_context_parse (context, &argc, &argv, &error);
1423
1424   if (!input) 
1425     { 
1426       g_fprintf (stderr, "no input files\n"); 
1427       
1428       return 1;
1429     }
1430
1431   if (includedirs != NULL)
1432     for (i = 0; includedirs[i]; i++)
1433       g_irepository_prepend_search_path (includedirs[i]);
1434
1435   for (i = 0; input[i]; i++)
1436     {
1437       GModule *dlhandle = NULL;
1438       const guchar *typelib;
1439       gsize len;
1440       const char *namespace;
1441
1442       if (!shlib)
1443         {
1444           if (!g_file_get_contents (input[i], (gchar **)&typelib, &len, &error))
1445             {
1446               g_fprintf (stderr, "failed to read '%s': %s\n", 
1447                          input[i], error->message);
1448               g_clear_error (&error);
1449               continue;
1450             }
1451         }
1452       else
1453         {
1454           typelib = load_typelib (input[i], &dlhandle, &len);
1455           if (!typelib)
1456             {
1457               g_fprintf (stderr, "failed to load typelib from '%s'\n", 
1458                          input[i]);
1459               continue;
1460             }
1461         }
1462
1463       if (input[i + 1] && output)
1464         needs_prefix = TRUE;
1465       else
1466         needs_prefix = FALSE;
1467
1468       data = g_typelib_new_from_const_memory (typelib, len);
1469       {
1470         GError *error = NULL;
1471         if (!g_typelib_validate (data, &error)) {
1472           g_printerr ("typelib not valid: %s\n", error->message);
1473           g_clear_error (&error);
1474           return 1;
1475         }
1476       }
1477       namespace = g_irepository_load_typelib (g_irepository_get_default (), data, 0,
1478                                               &error);
1479       if (namespace == NULL)
1480         {
1481           g_printerr ("failed to load typelib: %s\n", error->message);
1482           return 1;
1483         }
1484         
1485       write_repository (namespace, needs_prefix);
1486
1487       if (dlhandle)
1488         {
1489           g_module_close (dlhandle);
1490           dlhandle = NULL;
1491         }
1492
1493       /* when writing to stdout, stop after the first module */
1494       if (input[i + 1] && !output)
1495         {
1496           g_fprintf (stderr, "warning, %d modules omitted\n",
1497                      g_strv_length (input) - 1);
1498
1499           break;
1500         }
1501     }
1502       
1503   return 0;
1504 }