Fix unref sequence.
[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  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <errno.h>
23 #include <dlfcn.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
36 static void 
37 write_type_name (const gchar *namespace,
38                  GIBaseInfo  *info,
39                  FILE        *file)
40 {
41   if (strcmp (namespace, g_base_info_get_namespace (info)) != 0)
42     g_fprintf (file, "%s.", g_base_info_get_namespace (info));
43
44   g_fprintf (file, "%s", g_base_info_get_name (info));
45 }
46
47 static void
48 write_type_info (const gchar *namespace,
49                  GITypeInfo  *info, 
50                  FILE        *file)
51 {
52   gint tag;
53   gint i;
54   GITypeInfo *type;
55   
56   const gchar* basic[] = {
57     "none", 
58     "boolean", 
59     "int8", 
60     "uint8", 
61     "int16", 
62     "uint16", 
63     "int32", 
64     "uint32", 
65     "int64", 
66     "uint64", 
67     "int",
68     "uint",
69     "long",
70     "ulong",
71     "ssize",
72     "size",
73     "float", 
74     "double", 
75     "utf8",
76     "filename"
77   };
78
79   tag = g_type_info_get_tag (info);
80
81   if (tag < 18)
82     g_fprintf (file, "%s%s", basic[tag], g_type_info_is_pointer (info) ? "*" : "");
83   else if (tag < 20)
84     g_fprintf (file, "%s", basic[tag]);
85   else if (tag == 20)
86     {
87       gint length;
88
89       type = g_type_info_get_param_type (info, 0);
90       write_type_info (namespace, type, file);
91       g_fprintf (file, "["); 
92
93       length = g_type_info_get_array_length (info);
94       
95       if (length >= 0)
96         g_fprintf (file, "length=%d", length);
97       
98       if (g_type_info_is_zero_terminated (info))
99         g_fprintf (file, "%szero-terminated=1", length >= 0 ? "," : "");
100       
101      g_fprintf (file, "]"); 
102       g_base_info_unref ((GIBaseInfo *)type);
103     }
104   else if (tag == 21)
105     {
106       GIBaseInfo *iface = g_type_info_get_interface (info);
107       write_type_name (namespace, iface, file);
108       if (g_type_info_is_pointer (info))
109         g_fprintf (file, "*"); 
110       g_base_info_unref (iface);
111     }
112   else if (tag == 22)
113     {
114       type = g_type_info_get_param_type (info, 0);
115       g_fprintf (file, "GList");
116       if (type)
117         {
118           g_fprintf (file, "<"); 
119           write_type_info (namespace, type, file);
120           g_fprintf (file, ">"); 
121           g_base_info_unref ((GIBaseInfo *)type);
122         }
123       g_fprintf (file, "*");
124     }
125   else if (tag == 23)
126     {
127       type = g_type_info_get_param_type (info, 0);
128       g_fprintf (file, "GSList");
129       if (type)
130         {
131           g_fprintf (file, "<"); 
132           write_type_info (namespace, type, file);
133           g_fprintf (file, ">"); 
134           g_base_info_unref ((GIBaseInfo *)type);
135         }
136       g_fprintf (file, "*");
137     }
138   else if (tag == 24)
139     {
140       type = g_type_info_get_param_type (info, 0);
141       g_fprintf (file, "GHashTable");
142       if (type)
143         {
144           g_fprintf (file, "<"); 
145           write_type_info (namespace, type, file);
146           g_base_info_unref ((GIBaseInfo *)type);
147           type = g_type_info_get_param_type (info, 1);
148           g_fprintf (file, ",");
149           write_type_info (namespace, type, file);
150           g_fprintf (file, ">"); 
151           g_base_info_unref ((GIBaseInfo *)type);
152         }
153       g_fprintf (file, "*");
154     }
155   else if (tag == 25) 
156     {
157       gint n;
158
159       g_fprintf (file, "GError");
160       n = g_type_info_get_n_error_domains (info);
161       if (n > 0)
162         {
163           g_fprintf (file, "<"); 
164           for (i = 0; i < n; i++)
165             {
166               GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i);
167               if (i > 0)
168                 g_fprintf (file, ",");
169               write_type_name (namespace, (GIBaseInfo *)ed, file);
170               g_base_info_unref ((GIBaseInfo *)ed);
171             }
172           g_fprintf (file, ">");
173         }
174       g_fprintf (file, "*");
175     }
176 }
177
178 static void
179 write_constant_value (const gchar *namespace, 
180                       GITypeInfo *info,
181                       GArgument *argument,
182                       FILE *file);
183
184 static void
185 write_field_info (const gchar *namespace,
186                   GIFieldInfo *info,
187                   GIConstantInfo *branch,
188                   FILE        *file)
189 {
190   const gchar *name;
191   GIFieldInfoFlags flags;
192   gint size;
193   gint offset;
194   GITypeInfo *type;
195   GArgument value; 
196
197   name = g_base_info_get_name ((GIBaseInfo *)info);
198   flags = g_field_info_get_flags (info);
199   size = g_field_info_get_size (info);
200   offset = g_field_info_get_offset (info);
201
202   g_fprintf (file, 
203              "      <field name=\"%s\" readable=\"%s\" writable=\"%s\"",
204              name, 
205              flags & GI_FIELD_IS_READABLE ? "1" : "0", 
206              flags & GI_FIELD_IS_WRITABLE ? "1" : "0");
207   if (size)
208     g_fprintf (file, " bits=\"%d\"", size);
209
210   g_fprintf (file, " offset=\"%d\"", offset);
211
212   type = g_field_info_get_type (info);
213
214   if (branch)
215     {
216       g_fprintf (file, " branch=\"");
217       type = g_constant_info_get_type (branch);
218       g_constant_info_get_value (branch, &value);
219       write_constant_value (namespace, type, &value, file);
220       g_fprintf (file, "\"");
221     }
222
223   g_fprintf (file,">\n");
224
225   g_fprintf (file, "        <type name=\"");
226
227   write_type_info (namespace, type, file);
228   g_base_info_unref ((GIBaseInfo *)type);
229
230   g_fprintf (file, "\"/>\n");
231
232   g_fprintf (file,  "      </field>\n");
233
234 }
235
236 static void 
237 write_callable_info (const gchar    *namespace,
238                      GICallableInfo *info,
239                      FILE           *file,
240                      gint            indent)
241 {
242   GITypeInfo *type;
243   gint i;
244
245   type = g_callable_info_get_return_type (info);
246
247   if (g_type_info_is_pointer (type))
248     {
249       switch (g_callable_info_get_caller_owns (info))
250         {
251         case GI_TRANSFER_NOTHING:
252           g_fprintf (file, " transfer=\"none\"");
253           break;
254         case GI_TRANSFER_CONTAINER:
255           g_fprintf (file, " transfer=\"shallow\"");
256           break;
257         case GI_TRANSFER_EVERYTHING:
258           g_fprintf (file, " transfer=\"full\"");
259           break;
260         default:
261           g_assert_not_reached ();
262         }
263     }
264
265   g_fprintf (file, ">\n");
266
267   g_fprintf (file, "%*s  <return-value>\n", indent, "");
268   
269   if (g_callable_info_may_return_null (info))
270     g_fprintf (file, " null-ok=\"1\"");
271
272   g_fprintf (file, "%*s  <type name=\"", indent + 2, "");
273
274   write_type_info (namespace, type, file);
275
276   g_fprintf (file, "\"/>\n");
277
278   g_fprintf (file, "%*s  </return-value>\n", indent, "");
279         
280   if (g_callable_info_get_n_args (info) <= 0)
281     return;
282
283   g_fprintf (file, "%*s  <parameters>\n", indent, "");
284   for (i = 0; i < g_callable_info_get_n_args (info); i++)
285     {
286       GIArgInfo *arg = g_callable_info_get_arg (info, i);
287       
288       g_fprintf (file, "%*s    <parameter name=\"%s\"",
289                  indent, "", g_base_info_get_name ((GIBaseInfo *) arg));
290       
291       if (g_type_info_is_pointer (type))
292         {
293           switch (g_arg_info_get_ownership_transfer (arg))
294             {
295             case GI_TRANSFER_NOTHING:
296               g_fprintf (file, " transfer=\"none\"");
297               break;
298             case GI_TRANSFER_CONTAINER:
299               g_fprintf (file, " transfer=\"shallow\"");
300               break;
301             case GI_TRANSFER_EVERYTHING:
302               g_fprintf (file, " transfer=\"full\"");
303               break;
304             default:
305               g_assert_not_reached ();
306             }
307         }             
308       
309       g_fprintf (file, " direction=\"");
310       switch (g_arg_info_get_direction (arg))
311         {
312         case GI_DIRECTION_IN:
313           g_fprintf (file, "in");
314           break;
315         case GI_DIRECTION_OUT:
316           g_fprintf (file, "out");
317           break;
318         case GI_DIRECTION_INOUT:
319           g_fprintf (file, "inout");
320           break;
321         }
322       g_fprintf (file, "\"");
323       
324       if (g_arg_info_may_be_null (arg))
325         g_fprintf (file, " null-ok=\"1\"");
326       
327       if (g_arg_info_is_dipper (arg))
328         g_fprintf (file, " dipper=\"1\"");
329       
330       if (g_arg_info_is_return_value (arg))
331         g_fprintf (file, " retval=\"1\"");
332       
333       if (g_arg_info_is_optional (arg))
334         g_fprintf (file, " optional=\"1\"");
335       
336       g_fprintf (file, ">\n");
337       
338       g_fprintf (file, "%*s    <type name=\"", indent+2, "");
339
340       type = g_arg_info_get_type (arg);
341       write_type_info (namespace, type, file);
342
343       g_fprintf (file, "\"/>\n");
344       
345       g_fprintf (file, "%*s    </parameter>\n", indent, "");
346
347       g_base_info_unref ((GIBaseInfo *)arg);
348     }
349   
350   g_fprintf (file, "%*s  </parameters>\n", indent, "");
351   g_base_info_unref ((GIBaseInfo *)type);
352 }
353
354 static void
355 write_function_info (const gchar    *namespace,
356                      GIFunctionInfo *info,
357                      FILE           *file,
358                      gint            indent)
359 {
360   GIFunctionInfoFlags flags;
361   const gchar *tag;
362   const gchar *name;
363   const gchar *symbol;
364   gboolean deprecated;
365
366   flags = g_function_info_get_flags (info);
367   name = g_base_info_get_name ((GIBaseInfo *)info);
368   symbol = g_function_info_get_symbol (info);
369   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
370
371   if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
372     tag = "constructor";
373   else if (flags & GI_FUNCTION_IS_METHOD)
374     tag = "method";
375   else
376     tag = "function";
377         
378   g_fprintf (file, "%*s<%s name=\"%s\" c:identifier=\"%s\"", 
379              indent, "", tag, name, symbol);
380         
381   if (flags & GI_FUNCTION_IS_SETTER)
382     g_fprintf (file, " type=\"setter\"");
383   else if (flags & GI_FUNCTION_IS_GETTER)
384     g_fprintf (file, " type=\"getter\"");
385           
386   if (deprecated)
387     g_fprintf (file, " deprecated=\"1\"");
388         
389   write_callable_info (namespace, (GICallableInfo*)info, file, indent);
390   g_fprintf (file, "%*s</%s>\n", indent, "", tag);
391 }
392
393 static void
394 write_callback_info (const gchar    *namespace,
395                      GICallbackInfo *info,
396                      FILE           *file,
397                      gint            indent)
398 {
399   const gchar *name;
400   gboolean deprecated;
401
402   name = g_base_info_get_name ((GIBaseInfo *)info);
403   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
404
405   g_fprintf (file, "%*s<callback name=\"%s\"", indent, "", name);
406         
407   if (deprecated)
408     g_fprintf (file, " deprecated=\"1\"");
409         
410   write_callable_info (namespace, (GICallableInfo*)info, file, indent);
411   g_fprintf (file, "%*s</callback>\n", indent, "");
412 }
413
414 static void
415 write_struct_info (const gchar  *namespace,
416                    GIStructInfo *info,
417                    FILE         *file)
418 {
419   const gchar *name;
420   const gchar *type_name;
421   const gchar *type_init;
422   gboolean deprecated;
423   gint i;
424   int n_elts;
425
426   name = g_base_info_get_name ((GIBaseInfo *)info);
427   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
428
429   if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED)
430     {
431       type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
432       type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
433             
434       g_fprintf (file, "    <glib:boxed glib:name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"", name, type_name, type_init);
435     }
436   else
437     g_fprintf (file, "    <record name=\"%s\"", name);
438           
439   if (deprecated)
440     g_fprintf (file, " deprecated=\"1\"");
441         
442   n_elts = g_struct_info_get_n_fields (info) + g_struct_info_get_n_methods (info);
443   if (n_elts > 0)
444     {
445       g_fprintf (file, ">\n");
446       
447       for (i = 0; i < g_struct_info_get_n_fields (info); i++)
448         {
449           GIFieldInfo *field = g_struct_info_get_field (info, i);
450           write_field_info (namespace, field, NULL, file);
451           g_base_info_unref ((GIBaseInfo *)field);
452         }
453       
454       for (i = 0; i < g_struct_info_get_n_methods (info); i++)
455         {
456           GIFunctionInfo *function = g_struct_info_get_method (info, i);
457           write_function_info (namespace, function, file, 6);
458           g_base_info_unref ((GIBaseInfo *)function);
459         }
460       
461       if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED)
462         g_fprintf (file, "    </glib:boxed>\n");
463       else
464         g_fprintf (file, "    </record>\n");
465     } 
466   else
467     {
468       g_fprintf (file, "/>\n");
469     }
470 }
471
472 static void
473 write_value_info (const gchar *namespace,
474                   GIValueInfo *info,
475                   FILE        *file)
476 {
477   const gchar *name;
478   glong value;
479   gboolean deprecated;
480
481   name = g_base_info_get_name ((GIBaseInfo *)info);
482   value = g_value_info_get_value (info);
483   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
484
485   g_fprintf (file, "      <member name=\"%s\" value=\"%ld\"", name, value);
486
487   if (deprecated)
488     g_fprintf (file, " deprecated=\"1\"");
489   
490   g_fprintf (file, " />\n");
491 }
492
493 static void
494 write_constant_value (const gchar *namespace, 
495                       GITypeInfo *type,
496                       GArgument  *value,
497                       FILE       *file)
498 {
499   switch (g_type_info_get_tag (type))
500     {
501     case GI_TYPE_TAG_BOOLEAN:
502       g_fprintf (file, "%d", value->v_boolean);
503       break;
504     case GI_TYPE_TAG_INT8:
505       g_fprintf (file, "%d", value->v_int8);
506       break;
507     case GI_TYPE_TAG_UINT8:
508       g_fprintf (file, "%d", value->v_uint8);
509       break;
510     case GI_TYPE_TAG_INT16:
511       g_fprintf (file, "%" G_GINT16_FORMAT, value->v_int16);
512       break;
513     case GI_TYPE_TAG_UINT16:
514       g_fprintf (file, "%" G_GUINT16_FORMAT, value->v_uint16);
515       break;
516     case GI_TYPE_TAG_INT32:
517       g_fprintf (file, "%" G_GINT32_FORMAT, value->v_int32);
518       break;
519     case GI_TYPE_TAG_UINT32:
520       g_fprintf (file, "%" G_GUINT32_FORMAT, value->v_uint32);
521       break;
522     case GI_TYPE_TAG_INT64:
523       g_fprintf (file, "%" G_GINT64_FORMAT, value->v_int64);
524       break;
525     case GI_TYPE_TAG_UINT64:
526       g_fprintf (file, "%" G_GUINT64_FORMAT, value->v_uint64);
527       break;
528     case GI_TYPE_TAG_INT:
529       g_fprintf (file, "%d", value->v_int);
530       break;
531     case GI_TYPE_TAG_UINT:
532       g_fprintf (file, "%d", value->v_uint);
533       break;
534     case GI_TYPE_TAG_LONG:
535       g_fprintf (file, "%ld", value->v_long);
536       break;
537     case GI_TYPE_TAG_ULONG:
538       g_fprintf (file, "%ld", value->v_ulong);
539       break;
540     case GI_TYPE_TAG_SSIZE:
541       g_fprintf (file, "%zd", value->v_ssize);
542       break;
543     case GI_TYPE_TAG_SIZE:
544       g_fprintf (file, "%zd", value->v_size);
545       break;
546     case GI_TYPE_TAG_FLOAT:
547       g_fprintf (file, "%f", value->v_float);
548       break;
549     case GI_TYPE_TAG_DOUBLE:
550       g_fprintf (file, "%f", value->v_double);
551       break;
552     case GI_TYPE_TAG_UTF8:
553     case GI_TYPE_TAG_FILENAME:
554       g_fprintf (file, "%s", value->v_string);
555       break;
556     default:
557       g_assert_not_reached ();
558     }
559 }
560
561 static void
562 write_constant_info (const gchar    *namespace,
563                      GIConstantInfo *info,
564                      FILE           *file,
565                      gint            indent)
566 {
567   GITypeInfo *type;
568   const gchar *name;
569   gboolean deprecated;
570   GArgument value;
571
572   name = g_base_info_get_name ((GIBaseInfo *)info);
573   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
574
575   g_fprintf (file, "%*s<constant name=\"%s\"", indent, "", name);
576
577   type = g_constant_info_get_type (info);
578   g_fprintf (file, " value=\"");
579
580   g_constant_info_get_value (info, &value);
581   write_constant_value (namespace, type, &value, file);
582   g_fprintf (file, "\">\n");
583
584   g_fprintf (file, "%*s<type name=\"", indent + 2, "");
585
586   write_type_info (namespace, type, file);
587
588   g_fprintf (file, "\"/>\n");
589
590   g_fprintf (file, "%*s</constant>\n", indent, "");
591   
592   g_base_info_unref ((GIBaseInfo *)type);
593 }
594
595
596 static void
597 write_enum_info (const gchar *namespace,
598                  GIEnumInfo *info,
599                  FILE        *file)
600 {
601   const gchar *name;
602   const gchar *type_name;
603   const gchar *type_init;
604   gboolean deprecated;
605   gint i;
606
607   name = g_base_info_get_name ((GIBaseInfo *)info);
608   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
609
610   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
611   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
612
613   if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
614     g_fprintf (file, "    <enumeration ");
615   else
616     g_fprintf (file, "    <bitfield ");
617   g_fprintf (file, "name=\"%s\"", name);
618
619   if (type_init)
620     g_fprintf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
621   
622   if (deprecated)
623     g_fprintf (file, " deprecated=\"1\"");
624         
625   g_fprintf (file, ">\n");
626
627   for (i = 0; i < g_enum_info_get_n_values (info); i++)
628     {
629       GIValueInfo *value = g_enum_info_get_value (info, i);
630       write_value_info (namespace, value, file);
631       g_base_info_unref ((GIBaseInfo *)value);
632     }
633
634   if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
635     g_fprintf (file, "    </enumeration>\n");
636   else
637     g_fprintf (file, "    </bitfield>\n");
638 }
639
640 static void
641 write_signal_info (const gchar  *namespace,
642                    GISignalInfo *info,
643                    FILE         *file)
644 {
645   GSignalFlags flags;
646   const gchar *name;
647   gboolean deprecated;
648
649   name = g_base_info_get_name ((GIBaseInfo *)info);
650   flags = g_signal_info_get_flags (info);
651   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
652
653   g_fprintf (file, "      <glib:signal name=\"%s\"", name);
654
655   if (deprecated)
656     g_fprintf (file, " deprecated=\"1\"");
657         
658   if (flags & G_SIGNAL_RUN_FIRST)
659     g_fprintf (file, " when=\"FIRST\"");
660   else if (flags & G_SIGNAL_RUN_LAST)
661     g_fprintf (file, " when=\"LAST\"");
662   else if (flags & G_SIGNAL_RUN_CLEANUP)
663     g_fprintf (file, " when=\"CLEANUP\"");
664
665   if (flags & G_SIGNAL_NO_RECURSE)
666     g_fprintf (file, " no-recurse=\"1\"");
667
668   if (flags & G_SIGNAL_DETAILED)
669     g_fprintf (file, " detailed=\"1\"");
670
671   if (flags & G_SIGNAL_ACTION)
672     g_fprintf (file, " action=\"1\"");
673
674   if (flags & G_SIGNAL_NO_HOOKS)
675     g_fprintf (file, " no-hooks=\"1\"");
676
677   write_callable_info (namespace, (GICallableInfo*)info, file, 6);
678
679   g_fprintf (file, "      </glib:signal>\n");
680 }
681
682 static void
683 write_vfunc_info (const gchar *namespace, 
684                   GIVFuncInfo *info,
685                   FILE        *file)
686 {
687   GIVFuncInfoFlags flags;
688   const gchar *name;
689   gboolean deprecated;
690   gint offset;
691
692   name = g_base_info_get_name ((GIBaseInfo *)info);
693   flags = g_vfunc_info_get_flags (info);
694   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
695   offset = g_vfunc_info_get_offset (info);
696
697   g_fprintf (file, "      <vfunc name=\"%s\"", name);
698
699   if (deprecated)
700     g_fprintf (file, " deprecated=\"1\"");
701         
702   if (flags & GI_VFUNC_MUST_CHAIN_UP)
703     g_fprintf (file, " must-chain-up=\"1\"");
704
705   if (flags & GI_VFUNC_MUST_OVERRIDE)
706     g_fprintf (file, " override=\"always\"");
707   else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE)
708     g_fprintf (file, " override=\"never\"");
709     
710   g_fprintf (file, " offset=\"%d\"", offset);
711
712   write_callable_info (namespace, (GICallableInfo*)info, file, 6);
713
714   g_fprintf (file, "      </vfunc>\n");
715 }
716
717 static void
718 write_property_info (const gchar    *namespace,
719                      GIPropertyInfo *info,
720                      FILE           *file)
721 {
722   GParamFlags flags;
723   const gchar *name;
724   gboolean deprecated;
725   GITypeInfo *type;
726
727   name = g_base_info_get_name ((GIBaseInfo *)info);
728   flags = g_property_info_get_flags (info);
729   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
730
731   g_fprintf (file, "      <property name=\"%s\"", name);
732
733   if (deprecated)
734     g_fprintf (file, " deprecated=\"1\"");
735         
736   if (flags & G_PARAM_READABLE)
737     g_fprintf (file, " readable=\"1\"");
738   else
739     g_fprintf (file, " readable=\"0\"");
740
741   if (flags & G_PARAM_WRITABLE)
742     g_fprintf (file, " writable=\"1\"");
743   else
744     g_fprintf (file, " writable=\"0\"");
745
746   if (flags & G_PARAM_CONSTRUCT)
747     g_fprintf (file, " construct=\"1\"");
748
749   if (flags & G_PARAM_CONSTRUCT_ONLY)
750     g_fprintf (file, " construct-only=\"1\"");
751     
752   type = g_property_info_get_type (info);
753
754   g_fprintf (file, ">\n");
755
756   g_fprintf (file, "        <type name=\"", name);
757
758   write_type_info (namespace, type, file);
759
760   g_fprintf (file, "\"/>\n");
761   
762   g_fprintf (file, "      </property>\n");
763
764 }
765
766 static void
767 write_object_info (const gchar  *namespace, 
768                    GIObjectInfo *info,
769                    FILE         *file)
770 {
771   const gchar *name;
772   const gchar *type_name;
773   const gchar *type_init;
774   gboolean deprecated;
775   GIObjectInfo *pnode;
776   gint i;
777
778   name = g_base_info_get_name ((GIBaseInfo *)info);
779   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
780   
781   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
782   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
783   g_fprintf (file, "    <class name=\"%s\"", name);
784
785   pnode = g_object_info_get_parent (info);
786   if (pnode)
787     {
788       g_fprintf (file, " parent=\"");
789       write_type_name (namespace, (GIBaseInfo *)pnode, file);
790       g_fprintf (file, "\""  );
791       g_base_info_unref ((GIBaseInfo *)pnode);
792     }
793
794   g_fprintf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
795
796   if (deprecated)
797     g_fprintf (file, " deprecated=\"1\"");
798         
799   g_fprintf (file, ">\n");
800
801   if (g_object_info_get_n_interfaces (info) > 0)
802     {
803       g_fprintf (file, "      <implements>\n");
804       for (i = 0; i < g_object_info_get_n_interfaces (info); i++)
805         {
806           GIInterfaceInfo *imp = g_object_info_get_interface (info, i);
807           g_fprintf (file, "        <interface name=\"");
808           write_type_name (namespace, (GIBaseInfo*)imp, file);
809           g_fprintf (file,"\" />\n");
810           g_base_info_unref ((GIBaseInfo*)imp);
811         }
812       g_fprintf (file, "      </implements>\n");
813     }
814
815   for (i = 0; i < g_object_info_get_n_fields (info); i++)
816     {
817       GIFieldInfo *field = g_object_info_get_field (info, i);
818       write_field_info (namespace, field, NULL, file);
819       g_base_info_unref ((GIBaseInfo *)field);
820     }
821
822   for (i = 0; i < g_object_info_get_n_methods (info); i++)
823     {
824       GIFunctionInfo *function = g_object_info_get_method (info, i);
825       write_function_info (namespace, function, file, 6);
826       g_base_info_unref ((GIBaseInfo *)function);
827     }
828
829   for (i = 0; i < g_object_info_get_n_properties (info); i++)
830     {
831       GIPropertyInfo *prop = g_object_info_get_property (info, i);
832       write_property_info (namespace, prop, file);
833       g_base_info_unref ((GIBaseInfo *)prop);
834     }
835
836   for (i = 0; i < g_object_info_get_n_signals (info); i++)
837     {
838       GISignalInfo *signal = g_object_info_get_signal (info, i);
839       write_signal_info (namespace, signal, file);
840       g_base_info_unref ((GIBaseInfo *)signal);
841     }
842   
843   for (i = 0; i < g_object_info_get_n_vfuncs (info); i++)
844     {
845       GIVFuncInfo *vfunc = g_object_info_get_vfunc (info, i);
846       write_vfunc_info (namespace, vfunc, file);
847       g_base_info_unref ((GIBaseInfo *)vfunc);
848     }
849
850   for (i = 0; i < g_object_info_get_n_constants (info); i++)
851     {
852       GIConstantInfo *constant = g_object_info_get_constant (info, i);
853       write_constant_info (namespace, constant, file, 6);
854       g_base_info_unref ((GIBaseInfo *)constant);
855     }
856   
857   g_fprintf (file, "    </class>\n");
858 }
859
860 static void
861 write_interface_info (const gchar     *namespace,
862                       GIInterfaceInfo *info,
863                       FILE            *file)
864 {
865   const gchar *name;
866   const gchar *type_name;
867   const gchar *type_init;
868   gboolean deprecated;
869   gint i;
870
871   name = g_base_info_get_name ((GIBaseInfo *)info);
872   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
873
874   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
875   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
876   g_fprintf (file, "    <interface name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"",
877              name, type_name, type_init);
878
879   if (deprecated)
880     g_fprintf (file, " deprecated=\"1\"");
881         
882   g_fprintf (file, ">\n");
883
884   if (g_interface_info_get_n_prerequisites (info) > 0)
885     {
886       g_fprintf (file, "      <requires>\n");
887       for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++)
888         {
889           GIBaseInfo *req = g_interface_info_get_prerequisite (info, i);
890           
891           if (g_base_info_get_type (req) == GI_INFO_TYPE_INTERFACE)
892             g_fprintf (file, "      <interface name=\"");
893           else
894             g_fprintf (file, "      <object name=\"");
895           write_type_name (namespace, req, file);
896           g_fprintf (file, "\" />\n");
897           g_base_info_unref (req);
898         }
899       g_fprintf (file, "      </requires>\n");
900     }
901
902   for (i = 0; i < g_interface_info_get_n_methods (info); i++)
903     {
904       GIFunctionInfo *function = g_interface_info_get_method (info, i);
905       write_function_info (namespace, function, file, 6);
906       g_base_info_unref ((GIBaseInfo *)function);
907     }
908
909   for (i = 0; i < g_interface_info_get_n_properties (info); i++)
910     {
911       GIPropertyInfo *prop = g_interface_info_get_property (info, i);
912       write_property_info (namespace, prop, file);
913       g_base_info_unref ((GIBaseInfo *)prop);
914     }
915
916   for (i = 0; i < g_interface_info_get_n_signals (info); i++)
917     {
918       GISignalInfo *signal = g_interface_info_get_signal (info, i);
919       write_signal_info (namespace, signal, file);
920       g_base_info_unref ((GIBaseInfo *)signal);
921     }
922   
923   for (i = 0; i < g_interface_info_get_n_vfuncs (info); i++)
924     {
925       GIVFuncInfo *vfunc = g_interface_info_get_vfunc (info, i);
926       write_vfunc_info (namespace, vfunc, file);
927       g_base_info_unref ((GIBaseInfo *)vfunc);
928     }
929
930   for (i = 0; i < g_interface_info_get_n_constants (info); i++)
931     {
932       GIConstantInfo *constant = g_interface_info_get_constant (info, i);
933       write_constant_info (namespace, constant, file, 6);
934       g_base_info_unref ((GIBaseInfo *)constant);
935     }
936   
937   g_fprintf (file, "    </interface>\n");
938 }
939
940 static void
941 write_error_domain_info (const gchar       *namespace,
942                          GIErrorDomainInfo *info,
943                          FILE              *file)
944 {
945   GIBaseInfo *enum_;
946   const gchar *name, *quark;
947   
948   name = g_base_info_get_name ((GIBaseInfo *)info);
949   quark = g_error_domain_info_get_quark (info);
950   enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info);
951   g_fprintf (file,
952              "    <errordomain name=\"%s\" get-quark=\"%s\" codes=\"",
953              name, quark);
954   write_type_name (namespace, enum_, file);
955   g_fprintf (file, "\" />\n");
956   g_base_info_unref (enum_);
957 }
958
959 static void
960 write_union_info (const gchar *namespace, 
961                   GIUnionInfo *info, 
962                   FILE        *file)
963 {
964   const gchar *name;
965   const gchar *type_name;
966   const gchar *type_init;
967   gboolean deprecated;
968   gint i;
969
970   name = g_base_info_get_name ((GIBaseInfo *)info);
971   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
972
973   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
974   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
975   
976   g_fprintf (file, "    <union name=\"%s\"", name);
977   
978   if (type_name)
979     g_fprintf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
980           
981   if (deprecated)
982     g_fprintf (file, " deprecated=\"1\"");
983         
984   g_fprintf (file, ">\n");
985
986   if (g_union_info_is_discriminated (info))
987     {
988       gint offset;
989       GITypeInfo *type;
990
991       offset = g_union_info_get_discriminator_offset (info);
992       type = g_union_info_get_discriminator_type (info);
993       
994       g_fprintf (file, "      <discriminator offset=\"%d\" type=\"", offset);
995       write_type_info (namespace, type, file);
996       g_fprintf (file, "\" />\n");
997       g_base_info_unref ((GIBaseInfo *)type);
998     }
999
1000   for (i = 0; i < g_union_info_get_n_fields (info); i++)
1001     {
1002       GIFieldInfo *field = g_union_info_get_field (info, i);
1003       GIConstantInfo *constant = g_union_info_get_discriminator (info, i);
1004       write_field_info (namespace, field, constant, file);
1005       g_base_info_unref ((GIBaseInfo *)field);
1006       if (constant)
1007         g_base_info_unref ((GIBaseInfo *)constant);
1008     }
1009
1010   for (i = 0; i < g_union_info_get_n_methods (info); i++)
1011     {
1012       GIFunctionInfo *function = g_union_info_get_method (info, i);
1013       write_function_info (namespace, function, file, 6);
1014       g_base_info_unref ((GIBaseInfo *)function);
1015     }
1016
1017   g_fprintf (file, "    </union>\n");
1018 }
1019
1020 static void
1021 write_repository (GIRepository *repository,
1022                   gboolean      needs_prefix)
1023 {
1024   FILE *file;
1025   gchar **namespaces;
1026   gchar *ns;
1027   gint i, j;
1028
1029   namespaces = g_irepository_get_namespaces (repository);
1030
1031   if (output == NULL)
1032     file = stdout;
1033   else
1034     {
1035       gchar *filename;
1036       
1037       if (needs_prefix)
1038         filename = g_strdup_printf ("%s-%s", namespaces[0], output);  
1039       else
1040         filename = g_strdup (output);
1041       file = g_fopen (filename, "w");
1042       
1043       if (file == NULL)
1044         {
1045           g_fprintf (stderr, "failed to open '%s': %s\n",
1046                      filename, g_strerror (errno));
1047           g_free (filename);
1048           
1049           return;
1050         }
1051       
1052       g_free (filename);
1053     }
1054   
1055   g_fprintf (file, "<?xml version=\"1.0\"?>\n");
1056   g_fprintf (file, "<repository version=\"1.0\"\n"
1057              "            xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n"
1058              "            xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n"
1059              "            xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\">\n");
1060
1061   for (i = 0; namespaces[i]; i++)
1062     {
1063       const gchar *shared_library;
1064       ns = namespaces[i];
1065       shared_library = g_irepository_get_shared_library (repository, ns);
1066       if (shared_library)
1067         g_fprintf (file, "  <namespace name=\"%s\" shared-library=\"%s\">\n",
1068                    ns, shared_library);
1069       else
1070         g_fprintf (file, "  <namespace name=\"%s\">\n", ns);
1071       
1072       for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++)
1073         {
1074           GIBaseInfo *info = g_irepository_get_info (repository, ns, j);
1075           switch (g_base_info_get_type (info))
1076             {
1077             case GI_INFO_TYPE_FUNCTION:
1078               write_function_info (ns, (GIFunctionInfo *)info, file, 4);
1079               break;
1080               
1081             case GI_INFO_TYPE_CALLBACK:
1082               write_callback_info (ns, (GICallbackInfo *)info, file, 4);
1083               break;
1084
1085             case GI_INFO_TYPE_STRUCT:
1086             case GI_INFO_TYPE_BOXED:
1087               write_struct_info (ns, (GIStructInfo *)info, file);
1088               break;
1089
1090             case GI_INFO_TYPE_UNION:
1091               write_union_info (ns, (GIUnionInfo *)info, file);
1092               break;
1093
1094             case GI_INFO_TYPE_ENUM:
1095             case GI_INFO_TYPE_FLAGS:
1096               write_enum_info (ns, (GIEnumInfo *)info, file);
1097               break;
1098               
1099             case GI_INFO_TYPE_CONSTANT:
1100               write_constant_info (ns, (GIConstantInfo *)info, file, 4);
1101               break;
1102
1103             case GI_INFO_TYPE_OBJECT:
1104               write_object_info (ns, (GIObjectInfo *)info, file);
1105               break;
1106
1107             case GI_INFO_TYPE_INTERFACE:
1108               write_interface_info (ns, (GIInterfaceInfo *)info, file);
1109               break;
1110
1111             case GI_INFO_TYPE_ERROR_DOMAIN:
1112               write_error_domain_info (ns, (GIErrorDomainInfo *)info, file);
1113               break;
1114
1115             default:
1116               g_error ("unknown info type %d\n", g_base_info_get_type (info));
1117             }
1118
1119           g_base_info_unref (info);
1120         }
1121
1122       g_fprintf (file, "  </namespace>\n");
1123     }
1124
1125   g_fprintf (file, "</repository>\n");
1126       
1127   if (output != NULL)
1128     fclose (file);        
1129
1130   g_strfreev (namespaces);
1131 }
1132
1133 static const guchar *
1134 load_typelib (const gchar  *filename,
1135                GModule     **dlhandle,
1136                gsize        *len)
1137 {
1138   guchar *typelib;
1139   gsize *typelib_size;
1140   GModule *handle; 
1141
1142   handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
1143   if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &typelib))
1144     {
1145       g_printerr ("Could not load typelib from '%s': %s\n", 
1146                   filename, g_module_error ());
1147       return NULL;
1148     }
1149   
1150   if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &typelib_size))
1151     {
1152       g_printerr ("Could not load typelib from '%s': %s\n", 
1153                   filename, g_module_error ());
1154       return NULL;
1155     }
1156
1157   *len = *typelib_size;
1158   
1159   if (dlhandle)
1160     *dlhandle = handle;
1161
1162   return typelib;
1163 }
1164
1165 int 
1166 main (int argc, char *argv[])
1167 {  
1168   gboolean raw = FALSE;
1169   gchar **input = NULL;
1170   GOptionContext *context;
1171   GError *error = NULL;
1172   gboolean needs_prefix;
1173   gint i;
1174   GTypelib *data;
1175   GOptionEntry options[] = 
1176     {
1177       { "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "handle raw typelib", NULL },
1178       { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" }, 
1179       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL },
1180       { NULL, }
1181     };
1182
1183   g_type_init ();
1184
1185   g_typelib_check_sanity ();
1186
1187   context = g_option_context_new ("");
1188   g_option_context_add_main_entries (context, options, NULL);
1189   g_option_context_parse (context, &argc, &argv, &error);
1190
1191   if (!input) 
1192     { 
1193       g_fprintf (stderr, "no input files\n"); 
1194       
1195       return 1;
1196     }
1197
1198   for (i = 0; input[i]; i++)
1199     {
1200       GModule *dlhandle = NULL;
1201       const guchar *typelib;
1202       gsize len;
1203
1204       if (raw)
1205         {
1206           if (!g_file_get_contents (input[i], (gchar **)&typelib, &len, &error))
1207             {
1208               g_fprintf (stderr, "failed to read '%s': %s\n", 
1209                          input[i], error->message);
1210               g_clear_error (&error);
1211               continue;
1212             }
1213         }
1214       else
1215         {
1216           typelib = load_typelib (input[i], &dlhandle, &len);
1217           if (!typelib)
1218             {
1219               g_fprintf (stderr, "failed to load typelib from '%s'\n", 
1220                          input[i]);
1221               continue;
1222             }
1223         }
1224
1225       if (input[i + 1] && output)
1226         needs_prefix = TRUE;
1227       else
1228         needs_prefix = FALSE;
1229
1230       data = g_typelib_new_from_const_memory (typelib, len);
1231       {
1232         GError *error = NULL;
1233         if (!g_typelib_validate (data, &error)) {
1234           g_printerr ("typelib not valid: %s\n", error->message);
1235           g_clear_error (&error);
1236         }
1237       }
1238       g_irepository_register (g_irepository_get_default (), data);
1239       write_repository (g_irepository_get_default (), needs_prefix);
1240       g_irepository_unregister (g_irepository_get_default (),
1241                                 g_typelib_get_namespace (data));
1242
1243       if (dlhandle)
1244         {
1245           g_module_close (dlhandle);
1246           dlhandle = NULL;
1247         }
1248
1249       /* when writing to stdout, stop after the first module */
1250       if (input[i + 1] && !output)
1251         {
1252           g_fprintf (stderr, "warning, %d modules omitted\n",
1253                      g_strv_length (input) - 1);
1254
1255           break;
1256         }
1257     }
1258       
1259   return 0;
1260 }