Rename metadata to typelib in variable names, comments and apis.
[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     "void", 
58     "gboolean", 
59     "gint8", 
60     "guint8", 
61     "gint16", 
62     "guint16", 
63     "gint32", 
64     "guint32", 
65     "gint64", 
66     "guint64", 
67     "gint",
68     "guint",
69     "glong",
70     "gulong",
71     "gssize",
72     "gsize",
73     "gfloat", 
74     "gdouble", 
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   g_fprintf (file, "offset=\"%d\" ", offset);
210
211   g_fprintf (file, "type=\"");
212
213   type = g_field_info_get_type (info);
214   write_type_info (namespace, type, file);
215   g_base_info_unref ((GIBaseInfo *)type);
216
217   g_fprintf (file, "\"");
218
219   if (branch)
220     {
221       g_fprintf (file, " branch=\"");
222       type = g_constant_info_get_type (branch);
223       g_constant_info_get_value (branch, &value);
224       write_constant_value (namespace, type, &value, file);
225       g_fprintf (file, "\"");
226     }
227
228   g_fprintf (file," />\n");
229 }
230
231 static void 
232 write_callable_info (const gchar    *namespace,
233                      GICallableInfo *info,
234                      FILE           *file,
235                      gint            indent)
236 {
237   GITypeInfo *type;
238   gint i;
239
240   g_fprintf (file, "%*s  <return-type c:type=\"", indent, "");
241   
242   type = g_callable_info_get_return_type (info);
243   write_type_info (namespace, type, file);
244
245   g_fprintf (file, "\"");
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   g_base_info_unref ((GIBaseInfo *)type);
265   if (g_callable_info_may_return_null (info))
266     g_fprintf (file, " null-ok=\"1\"");
267
268   g_fprintf (file, " />\n");
269         
270   if (g_callable_info_get_n_args (info) > 0)
271     {
272       g_fprintf (file, "%*s  <parameters>\n", indent, "");
273       for (i = 0; i < g_callable_info_get_n_args (info); i++)
274         {
275           GIArgInfo *arg = g_callable_info_get_arg (info, i);
276                 
277           g_fprintf (file, "%*s    <parameter name=\"%s\" c:type=\"",
278                      indent, "", g_base_info_get_name ((GIBaseInfo *) arg));
279                 
280           type = g_arg_info_get_type (arg);
281           write_type_info (namespace, type, file);
282           g_fprintf (file, "\"");
283
284           if (g_type_info_is_pointer (type))
285             {
286               switch (g_arg_info_get_ownership_transfer (arg))
287                 {
288                 case GI_TRANSFER_NOTHING:
289                   g_fprintf (file, " transfer=\"none\"");
290                   break;
291                 case GI_TRANSFER_CONTAINER:
292                   g_fprintf (file, " transfer=\"shallow\"");
293                   break;
294                 case GI_TRANSFER_EVERYTHING:
295                   g_fprintf (file, " transfer=\"full\"");
296                   break;
297                 default:
298                   g_assert_not_reached ();
299                 }
300             }         
301           g_base_info_unref ((GIBaseInfo *)type);
302
303           g_fprintf (file, " direction=\"");
304           switch (g_arg_info_get_direction (arg))
305             {
306             case GI_DIRECTION_IN:
307               g_fprintf (file, "in");
308               break;
309             case GI_DIRECTION_OUT:
310               g_fprintf (file, "out");
311               break;
312             case GI_DIRECTION_INOUT:
313               g_fprintf (file, "inout");
314               break;
315             }
316           g_fprintf (file, "\"");
317
318           if (g_arg_info_may_be_null (arg))
319             g_fprintf (file, " null-ok=\"1\"");
320           
321           if (g_arg_info_is_dipper (arg))
322             g_fprintf (file, " dipper=\"1\"");
323           
324           if (g_arg_info_is_return_value (arg))
325             g_fprintf (file, " retval=\"1\"");
326           
327           if (g_arg_info_is_optional (arg))
328             g_fprintf (file, " optional=\"1\"");
329           
330           g_fprintf (file, " />\n");
331                 
332           g_base_info_unref ((GIBaseInfo *)arg);
333         }
334             
335       g_fprintf (file, "%*s  </parameters>\n", indent, "");
336     }
337 }
338
339 static void
340 write_function_info (const gchar    *namespace,
341                      GIFunctionInfo *info,
342                      FILE           *file,
343                      gint            indent)
344 {
345   GIFunctionInfoFlags flags;
346   const gchar *tag;
347   const gchar *name;
348   const gchar *symbol;
349   gboolean deprecated;
350
351   flags = g_function_info_get_flags (info);
352   name = g_base_info_get_name ((GIBaseInfo *)info);
353   symbol = g_function_info_get_symbol (info);
354   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
355
356   if (flags & GI_FUNCTION_IS_CONSTRUCTOR)
357     tag = "constructor";
358   else if (flags & GI_FUNCTION_IS_METHOD)
359     tag = "method";
360   else
361     tag = "function";
362         
363   g_fprintf (file, "%*s<%s name=\"%s\" c:identifier=\"%s\"", 
364              indent, "", tag, name, symbol);
365         
366   if (flags & GI_FUNCTION_IS_SETTER)
367     g_fprintf (file, " type=\"setter\"");
368   else if (flags & GI_FUNCTION_IS_GETTER)
369     g_fprintf (file, " type=\"getter\"");
370           
371   if (deprecated)
372     g_fprintf (file, " deprecated=\"1\"");
373         
374   g_fprintf (file, ">\n");
375   write_callable_info (namespace, (GICallableInfo*)info, file, indent);
376   g_fprintf (file, "%*s</%s>\n", indent, "", tag);
377 }
378
379 static void
380 write_callback_info (const gchar    *namespace,
381                      GICallbackInfo *info,
382                      FILE           *file,
383                      gint            indent)
384 {
385   const gchar *name;
386   gboolean deprecated;
387
388   name = g_base_info_get_name ((GIBaseInfo *)info);
389   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
390
391   g_fprintf (file, "%*s<callback name=\"%s\"", indent, "", name);
392         
393   if (deprecated)
394     g_fprintf (file, " deprecated=\"1\"");
395         
396   g_fprintf (file, ">\n");
397   write_callable_info (namespace, (GICallableInfo*)info, file, indent);
398   g_fprintf (file, "%*s</callback>\n", indent, "");
399 }
400
401 static void
402 write_struct_info (const gchar  *namespace,
403                    GIStructInfo *info,
404                    FILE         *file)
405 {
406   const gchar *name;
407   const gchar *type_name;
408   const gchar *type_init;
409   gboolean deprecated;
410   gint i;
411
412   name = g_base_info_get_name ((GIBaseInfo *)info);
413   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
414
415   if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED)
416     {
417       type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
418       type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
419             
420       g_fprintf (file, "    <boxed name=\"%s\" type-name=\"%s\" get-type=\"%s\"", name, type_name, type_init);
421     }
422   else
423     g_fprintf (file, "    <struct name=\"%s\"", name);
424           
425   if (deprecated)
426     g_fprintf (file, " deprecated=\"1\"");
427         
428   g_fprintf (file, ">\n");
429
430   for (i = 0; i < g_struct_info_get_n_fields (info); i++)
431     {
432       GIFieldInfo *field = g_struct_info_get_field (info, i);
433       write_field_info (namespace, field, NULL, file);
434       g_base_info_unref ((GIBaseInfo *)field);
435     }
436
437   for (i = 0; i < g_struct_info_get_n_methods (info); i++)
438     {
439       GIFunctionInfo *function = g_struct_info_get_method (info, i);
440       write_function_info (namespace, function, file, 6);
441       g_base_info_unref ((GIBaseInfo *)function);
442     }
443
444   if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED)
445     g_fprintf (file, "    </boxed>\n");
446   else
447     g_fprintf (file, "    </struct>\n");
448 }
449
450 static void
451 write_value_info (const gchar *namespace,
452                   GIValueInfo *info,
453                   FILE        *file)
454 {
455   const gchar *name;
456   glong value;
457   gboolean deprecated;
458
459   name = g_base_info_get_name ((GIBaseInfo *)info);
460   value = g_value_info_get_value (info);
461   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
462
463   g_fprintf (file, "      <member name=\"%s\" value=\"%ld\"", name, value);
464
465   if (deprecated)
466     g_fprintf (file, " deprecated=\"1\"");
467   
468   g_fprintf (file, " />\n");
469 }
470
471 static void
472 write_constant_value (const gchar *namespace, 
473                       GITypeInfo *type,
474                       GArgument  *value,
475                       FILE       *file)
476 {
477   switch (g_type_info_get_tag (type))
478     {
479     case GI_TYPE_TAG_BOOLEAN:
480       g_fprintf (file, "%d", value->v_boolean);
481       break;
482     case GI_TYPE_TAG_INT8:
483       g_fprintf (file, "%d", value->v_int8);
484       break;
485     case GI_TYPE_TAG_UINT8:
486       g_fprintf (file, "%d", value->v_uint8);
487       break;
488     case GI_TYPE_TAG_INT16:
489       g_fprintf (file, "%" G_GINT16_FORMAT, value->v_int16);
490       break;
491     case GI_TYPE_TAG_UINT16:
492       g_fprintf (file, "%" G_GUINT16_FORMAT, value->v_uint16);
493       break;
494     case GI_TYPE_TAG_INT32:
495       g_fprintf (file, "%" G_GINT32_FORMAT, value->v_int32);
496       break;
497     case GI_TYPE_TAG_UINT32:
498       g_fprintf (file, "%" G_GUINT32_FORMAT, value->v_uint32);
499       break;
500     case GI_TYPE_TAG_INT64:
501       g_fprintf (file, "%" G_GINT64_FORMAT, value->v_int64);
502       break;
503     case GI_TYPE_TAG_UINT64:
504       g_fprintf (file, "%" G_GUINT64_FORMAT, value->v_uint64);
505       break;
506     case GI_TYPE_TAG_INT:
507       g_fprintf (file, "%d", value->v_int);
508       break;
509     case GI_TYPE_TAG_UINT:
510       g_fprintf (file, "%d", value->v_uint);
511       break;
512     case GI_TYPE_TAG_LONG:
513       g_fprintf (file, "%ld", value->v_long);
514       break;
515     case GI_TYPE_TAG_ULONG:
516       g_fprintf (file, "%ld", value->v_ulong);
517       break;
518     case GI_TYPE_TAG_SSIZE:
519       g_fprintf (file, "%zd", value->v_ssize);
520       break;
521     case GI_TYPE_TAG_SIZE:
522       g_fprintf (file, "%zd", value->v_size);
523       break;
524     case GI_TYPE_TAG_FLOAT:
525       g_fprintf (file, "%f", value->v_float);
526       break;
527     case GI_TYPE_TAG_DOUBLE:
528       g_fprintf (file, "%f", value->v_double);
529       break;
530     case GI_TYPE_TAG_UTF8:
531     case GI_TYPE_TAG_FILENAME:
532       g_fprintf (file, "%s", value->v_string);
533       break;
534     default:
535       g_assert_not_reached ();
536     }
537 }
538
539 static void
540 write_constant_info (const gchar    *namespace,
541                      GIConstantInfo *info,
542                      FILE           *file,
543                      gint            indent)
544 {
545   GITypeInfo *type;
546   const gchar *name;
547   gboolean deprecated;
548   GArgument value;
549
550   name = g_base_info_get_name ((GIBaseInfo *)info);
551   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
552
553   g_fprintf (file, "%*s<constant name=\"%s\" type=\"", indent, "", name);
554
555   type = g_constant_info_get_type (info);
556   write_type_info (namespace, type, file);
557   g_fprintf (file, "\" value=\"");
558
559   g_constant_info_get_value (info, &value);
560   write_constant_value (namespace, type, &value, file);
561   g_fprintf (file, "\" />\n");
562   
563   g_base_info_unref ((GIBaseInfo *)type);
564 }
565
566
567 static void
568 write_enum_info (const gchar *namespace,
569                  GIEnumInfo *info,
570                  FILE        *file)
571 {
572   const gchar *name;
573   const gchar *type_name;
574   const gchar *type_init;
575   gboolean deprecated;
576   gint i;
577
578   name = g_base_info_get_name ((GIBaseInfo *)info);
579   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
580
581   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
582   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
583
584   if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
585     g_fprintf (file, "    <enum ");
586   else
587     g_fprintf (file, "    <flags ");
588   g_fprintf (file, "name=\"%s\"", name);
589
590   if (type_init)
591     g_fprintf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
592   
593   if (deprecated)
594     g_fprintf (file, " deprecated=\"1\"");
595         
596   g_fprintf (file, ">\n");
597
598   for (i = 0; i < g_enum_info_get_n_values (info); i++)
599     {
600       GIValueInfo *value = g_enum_info_get_value (info, i);
601       write_value_info (namespace, value, file);
602       g_base_info_unref ((GIBaseInfo *)value);
603     }
604
605   if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
606     g_fprintf (file, "    </enum>\n");
607   else
608     g_fprintf (file, "    </flags>\n");
609 }
610
611 static void
612 write_signal_info (const gchar  *namespace,
613                    GISignalInfo *info,
614                    FILE         *file)
615 {
616   GSignalFlags flags;
617   const gchar *name;
618   gboolean deprecated;
619
620   name = g_base_info_get_name ((GIBaseInfo *)info);
621   flags = g_signal_info_get_flags (info);
622   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
623
624   g_fprintf (file, "      <signal name=\"%s\"", name);
625
626   if (deprecated)
627     g_fprintf (file, " deprecated=\"1\"");
628         
629   if (flags & G_SIGNAL_RUN_FIRST)
630     g_fprintf (file, " when=\"FIRST\"");
631   else if (flags & G_SIGNAL_RUN_LAST)
632     g_fprintf (file, " when=\"LAST\"");
633   else if (flags & G_SIGNAL_RUN_CLEANUP)
634     g_fprintf (file, " when=\"CLEANUP\"");
635
636   if (flags & G_SIGNAL_NO_RECURSE)
637     g_fprintf (file, " no-recurse=\"1\"");
638
639   if (flags & G_SIGNAL_DETAILED)
640     g_fprintf (file, " detailed=\"1\"");
641
642   if (flags & G_SIGNAL_ACTION)
643     g_fprintf (file, " action=\"1\"");
644
645   if (flags & G_SIGNAL_NO_HOOKS)
646     g_fprintf (file, " no-hooks=\"1\"");
647
648   g_fprintf (file, ">\n");
649
650   write_callable_info (namespace, (GICallableInfo*)info, file, 6);
651   g_fprintf (file, "      </signal>\n");
652 }
653
654 static void
655 write_vfunc_info (const gchar *namespace, 
656                   GIVFuncInfo *info,
657                   FILE        *file)
658 {
659   GIVFuncInfoFlags flags;
660   const gchar *name;
661   gboolean deprecated;
662   gint offset;
663
664   name = g_base_info_get_name ((GIBaseInfo *)info);
665   flags = g_vfunc_info_get_flags (info);
666   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
667   offset = g_vfunc_info_get_offset (info);
668
669   g_fprintf (file, "      <vfunc name=\"%s\"", name);
670
671   if (deprecated)
672     g_fprintf (file, " deprecated=\"1\"");
673         
674   if (flags & GI_VFUNC_MUST_CHAIN_UP)
675     g_fprintf (file, " must-chain-up=\"1\"");
676
677   if (flags & GI_VFUNC_MUST_OVERRIDE)
678     g_fprintf (file, " override=\"always\"");
679   else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE)
680     g_fprintf (file, " override=\"never\"");
681     
682   g_fprintf (file, " offset=\"%d\"", offset);
683   g_fprintf (file, ">\n");
684
685   write_callable_info (namespace, (GICallableInfo*)info, file, 6);
686   g_fprintf (file, "      </vfunc>\n");
687 }
688
689 static void
690 write_property_info (const gchar    *namespace,
691                      GIPropertyInfo *info,
692                      FILE           *file)
693 {
694   GParamFlags flags;
695   const gchar *name;
696   gboolean deprecated;
697   GITypeInfo *type;
698
699   name = g_base_info_get_name ((GIBaseInfo *)info);
700   flags = g_property_info_get_flags (info);
701   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
702
703   g_fprintf (file, "      <property name=\"%s\"", name);
704
705   if (deprecated)
706     g_fprintf (file, " deprecated=\"1\"");
707         
708   if (flags & G_PARAM_READABLE)
709     g_fprintf (file, " readable=\"1\"");
710   else
711     g_fprintf (file, " readable=\"0\"");
712
713   if (flags & G_PARAM_WRITABLE)
714     g_fprintf (file, " writable=\"1\"");
715   else
716     g_fprintf (file, " writable=\"0\"");
717
718   if (flags & G_PARAM_CONSTRUCT)
719     g_fprintf (file, " construct=\"1\"");
720
721   if (flags & G_PARAM_CONSTRUCT_ONLY)
722     g_fprintf (file, " construct-only=\"1\"");
723     
724   type = g_property_info_get_type (info);
725   g_fprintf (file, " type=\"");
726   write_type_info (namespace, type, file);
727   g_fprintf (file, "\"");
728
729   g_fprintf (file, " />\n");
730 }
731
732 static void
733 write_object_info (const gchar  *namespace, 
734                    GIObjectInfo *info,
735                    FILE         *file)
736 {
737   const gchar *name;
738   const gchar *type_name;
739   const gchar *type_init;
740   gboolean deprecated;
741   GIObjectInfo *pnode;
742   gint i;
743
744   name = g_base_info_get_name ((GIBaseInfo *)info);
745   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
746   
747   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
748   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
749   g_fprintf (file, "    <object name=\"%s\"", name);
750
751   pnode = g_object_info_get_parent (info);
752   if (pnode)
753     {
754       g_fprintf (file, " parent=\"");
755       write_type_name (namespace, (GIBaseInfo *)pnode, file);
756       g_fprintf (file, "\""  );
757       g_base_info_unref ((GIBaseInfo *)pnode);
758     }
759
760   g_fprintf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
761
762   if (deprecated)
763     g_fprintf (file, " deprecated=\"1\"");
764         
765   g_fprintf (file, ">\n");
766
767   if (g_object_info_get_n_interfaces (info) > 0)
768     {
769       g_fprintf (file, "      <implements>\n");
770       for (i = 0; i < g_object_info_get_n_interfaces (info); i++)
771         {
772           GIInterfaceInfo *imp = g_object_info_get_interface (info, i);
773           g_fprintf (file, "        <interface name=\"");
774           write_type_name (namespace, (GIBaseInfo*)imp, file);
775           g_fprintf (file,"\" />\n");
776           g_base_info_unref ((GIBaseInfo*)imp);
777         }
778       g_fprintf (file, "      </implements>\n");
779     }
780
781   for (i = 0; i < g_object_info_get_n_fields (info); i++)
782     {
783       GIFieldInfo *field = g_object_info_get_field (info, i);
784       write_field_info (namespace, field, NULL, file);
785       g_base_info_unref ((GIBaseInfo *)field);
786     }
787
788   for (i = 0; i < g_object_info_get_n_methods (info); i++)
789     {
790       GIFunctionInfo *function = g_object_info_get_method (info, i);
791       write_function_info (namespace, function, file, 6);
792       g_base_info_unref ((GIBaseInfo *)function);
793     }
794
795   for (i = 0; i < g_object_info_get_n_properties (info); i++)
796     {
797       GIPropertyInfo *prop = g_object_info_get_property (info, i);
798       write_property_info (namespace, prop, file);
799       g_base_info_unref ((GIBaseInfo *)prop);
800     }
801
802   for (i = 0; i < g_object_info_get_n_signals (info); i++)
803     {
804       GISignalInfo *signal = g_object_info_get_signal (info, i);
805       write_signal_info (namespace, signal, file);
806       g_base_info_unref ((GIBaseInfo *)signal);
807     }
808   
809   for (i = 0; i < g_object_info_get_n_vfuncs (info); i++)
810     {
811       GIVFuncInfo *vfunc = g_object_info_get_vfunc (info, i);
812       write_vfunc_info (namespace, vfunc, file);
813       g_base_info_unref ((GIBaseInfo *)vfunc);
814     }
815
816   for (i = 0; i < g_object_info_get_n_constants (info); i++)
817     {
818       GIConstantInfo *constant = g_object_info_get_constant (info, i);
819       write_constant_info (namespace, constant, file, 6);
820       g_base_info_unref ((GIBaseInfo *)constant);
821     }
822   
823   g_fprintf (file, "    </object>\n");
824 }
825
826 static void
827 write_interface_info (const gchar     *namespace,
828                       GIInterfaceInfo *info,
829                       FILE            *file)
830 {
831   const gchar *name;
832   const gchar *type_name;
833   const gchar *type_init;
834   gboolean deprecated;
835   gint i;
836
837   name = g_base_info_get_name ((GIBaseInfo *)info);
838   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
839
840   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
841   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
842   g_fprintf (file, "    <interface name=\"%s\" type-name=\"%s\" get-type=\"%s\"",
843              name, type_name, type_init);
844
845   if (deprecated)
846     g_fprintf (file, " deprecated=\"1\"");
847         
848   g_fprintf (file, ">\n");
849
850   if (g_interface_info_get_n_prerequisites (info) > 0)
851     {
852       g_fprintf (file, "      <requires>\n");
853       for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++)
854         {
855           GIBaseInfo *req = g_interface_info_get_prerequisite (info, i);
856           
857           if (g_base_info_get_type (req) == GI_INFO_TYPE_INTERFACE)
858             g_fprintf (file, "      <interface name=\"");
859           else
860             g_fprintf (file, "      <object name=\"");
861           write_type_name (namespace, req, file);
862           g_fprintf (file, "\" />\n");
863           g_base_info_unref (req);
864         }
865       g_fprintf (file, "      </requires>\n");
866     }
867
868   for (i = 0; i < g_interface_info_get_n_methods (info); i++)
869     {
870       GIFunctionInfo *function = g_interface_info_get_method (info, i);
871       write_function_info (namespace, function, file, 6);
872       g_base_info_unref ((GIBaseInfo *)function);
873     }
874
875   for (i = 0; i < g_interface_info_get_n_properties (info); i++)
876     {
877       GIPropertyInfo *prop = g_interface_info_get_property (info, i);
878       write_property_info (namespace, prop, file);
879       g_base_info_unref ((GIBaseInfo *)prop);
880     }
881
882   for (i = 0; i < g_interface_info_get_n_signals (info); i++)
883     {
884       GISignalInfo *signal = g_interface_info_get_signal (info, i);
885       write_signal_info (namespace, signal, file);
886       g_base_info_unref ((GIBaseInfo *)signal);
887     }
888   
889   for (i = 0; i < g_interface_info_get_n_vfuncs (info); i++)
890     {
891       GIVFuncInfo *vfunc = g_interface_info_get_vfunc (info, i);
892       write_vfunc_info (namespace, vfunc, file);
893       g_base_info_unref ((GIBaseInfo *)vfunc);
894     }
895
896   for (i = 0; i < g_interface_info_get_n_constants (info); i++)
897     {
898       GIConstantInfo *constant = g_interface_info_get_constant (info, i);
899       write_constant_info (namespace, constant, file, 6);
900       g_base_info_unref ((GIBaseInfo *)constant);
901     }
902   
903   g_fprintf (file, "    </interface>\n");
904 }
905
906 static void
907 write_error_domain_info (const gchar       *namespace,
908                          GIErrorDomainInfo *info,
909                          FILE              *file)
910 {
911   GIBaseInfo *enum_;
912   const gchar *name, *quark;
913   
914   name = g_base_info_get_name ((GIBaseInfo *)info);
915   quark = g_error_domain_info_get_quark (info);
916   enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info);
917   g_fprintf (file,
918              "    <errordomain name=\"%s\" get-quark=\"%s\" codes=\"",
919              name, quark);
920   write_type_name (namespace, enum_, file);
921   g_fprintf (file, "\" />\n");
922   g_base_info_unref (enum_);
923 }
924
925 static void
926 write_union_info (const gchar *namespace, 
927                   GIUnionInfo *info, 
928                   FILE        *file)
929 {
930   const gchar *name;
931   const gchar *type_name;
932   const gchar *type_init;
933   gboolean deprecated;
934   gint i;
935
936   name = g_base_info_get_name ((GIBaseInfo *)info);
937   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
938
939   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
940   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
941   
942   g_fprintf (file, "    <union name=\"%s\"", name);
943   
944   if (type_name)
945     g_fprintf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init);
946           
947   if (deprecated)
948     g_fprintf (file, " deprecated=\"1\"");
949         
950   g_fprintf (file, ">\n");
951
952   if (g_union_info_is_discriminated (info))
953     {
954       gint offset;
955       GITypeInfo *type;
956
957       offset = g_union_info_get_discriminator_offset (info);
958       type = g_union_info_get_discriminator_type (info);
959       
960       g_fprintf (file, "      <discriminator offset=\"%d\" type=\"", offset);
961       write_type_info (namespace, type, file);
962       g_fprintf (file, "\" />\n");
963       g_base_info_unref ((GIBaseInfo *)type);
964     }
965
966   for (i = 0; i < g_union_info_get_n_fields (info); i++)
967     {
968       GIFieldInfo *field = g_union_info_get_field (info, i);
969       GIConstantInfo *constant = g_union_info_get_discriminator (info, i);
970       write_field_info (namespace, field, constant, file);
971       g_base_info_unref ((GIBaseInfo *)field);
972       if (constant)
973         g_base_info_unref ((GIBaseInfo *)constant);
974     }
975
976   for (i = 0; i < g_union_info_get_n_methods (info); i++)
977     {
978       GIFunctionInfo *function = g_union_info_get_method (info, i);
979       write_function_info (namespace, function, file, 6);
980       g_base_info_unref ((GIBaseInfo *)function);
981     }
982
983   g_fprintf (file, "    </union>\n");
984 }
985
986 static void
987 write_repository (GIRepository *repository,
988                   gboolean      needs_prefix)
989 {
990   FILE *file;
991   gchar **namespaces;
992   gchar *ns;
993   gint i, j;
994
995   namespaces = g_irepository_get_namespaces (repository);
996
997   if (output == NULL)
998     file = stdout;
999   else
1000     {
1001       gchar *filename;
1002       
1003       if (needs_prefix)
1004         filename = g_strdup_printf ("%s-%s", namespaces[0], output);  
1005       else
1006         filename = g_strdup (output);
1007       file = g_fopen (filename, "w");
1008       
1009       if (file == NULL)
1010         {
1011           g_fprintf (stderr, "failed to open '%s': %s\n",
1012                      filename, g_strerror (errno));
1013           g_free (filename);
1014           
1015           return;
1016         }
1017       
1018       g_free (filename);
1019     }
1020   
1021   g_fprintf (file, "<?xml version=\"1.0\"?>\n");
1022   g_fprintf (file, "<repository version=\"1.0\"\n"
1023              "            xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n"
1024              "            xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n"
1025              "            xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\">\n");
1026
1027   for (i = 0; namespaces[i]; i++)
1028     {
1029       const gchar *shared_library;
1030       ns = namespaces[i];
1031       shared_library = g_irepository_get_shared_library (repository, ns);
1032       if (shared_library)
1033         g_fprintf (file, "  <namespace name=\"%s\" shared-library=\"%s\">\n",
1034                    ns, shared_library);
1035       else
1036         g_fprintf (file, "  <namespace name=\"%s\">\n", ns);
1037       
1038       for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++)
1039         {
1040           GIBaseInfo *info = g_irepository_get_info (repository, ns, j);
1041           switch (g_base_info_get_type (info))
1042             {
1043             case GI_INFO_TYPE_FUNCTION:
1044               write_function_info (ns, (GIFunctionInfo *)info, file, 4);
1045               break;
1046               
1047             case GI_INFO_TYPE_CALLBACK:
1048               write_callback_info (ns, (GICallbackInfo *)info, file, 4);
1049               break;
1050
1051             case GI_INFO_TYPE_STRUCT:
1052             case GI_INFO_TYPE_BOXED:
1053               write_struct_info (ns, (GIStructInfo *)info, file);
1054               break;
1055
1056             case GI_INFO_TYPE_UNION:
1057               write_union_info (ns, (GIUnionInfo *)info, file);
1058               break;
1059
1060             case GI_INFO_TYPE_ENUM:
1061             case GI_INFO_TYPE_FLAGS:
1062               write_enum_info (ns, (GIEnumInfo *)info, file);
1063               break;
1064               
1065             case GI_INFO_TYPE_CONSTANT:
1066               write_constant_info (ns, (GIConstantInfo *)info, file, 4);
1067               break;
1068
1069             case GI_INFO_TYPE_OBJECT:
1070               write_object_info (ns, (GIObjectInfo *)info, file);
1071               break;
1072
1073             case GI_INFO_TYPE_INTERFACE:
1074               write_interface_info (ns, (GIInterfaceInfo *)info, file);
1075               break;
1076
1077             case GI_INFO_TYPE_ERROR_DOMAIN:
1078               write_error_domain_info (ns, (GIErrorDomainInfo *)info, file);
1079               break;
1080
1081             default:
1082               g_error ("unknown info type %d\n", g_base_info_get_type (info));
1083             }
1084
1085           g_base_info_unref (info);
1086         }
1087
1088       g_fprintf (file, "  </namespace>\n");
1089     }
1090
1091   g_fprintf (file, "</repository>\n");
1092       
1093   if (output != NULL)
1094     fclose (file);        
1095
1096   g_strfreev (namespaces);
1097 }
1098
1099 static const guchar *
1100 load_typelib (const gchar  *filename,
1101                GModule     **dlhandle,
1102                gsize        *len)
1103 {
1104   guchar *typelib;
1105   gsize *typelib_size;
1106   GModule *handle; 
1107
1108   handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
1109   if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &typelib))
1110     {
1111       g_printerr ("Could not load typelib from '%s': %s\n", 
1112                   filename, g_module_error ());
1113       return NULL;
1114     }
1115   
1116   if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &typelib_size))
1117     {
1118       g_printerr ("Could not load typelib from '%s': %s\n", 
1119                   filename, g_module_error ());
1120       return NULL;
1121     }
1122
1123   *len = *typelib_size;
1124   
1125   if (dlhandle)
1126     *dlhandle = handle;
1127
1128   return typelib;
1129 }
1130
1131 int 
1132 main (int argc, char *argv[])
1133 {  
1134   gboolean raw = FALSE;
1135   gchar **input = NULL;
1136   GOptionContext *context;
1137   GError *error = NULL;
1138   gboolean needs_prefix;
1139   gint i;
1140   GTypelib *data;
1141   GOptionEntry options[] = 
1142     {
1143       { "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "handle raw typelib", NULL },
1144       { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" }, 
1145       { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL },
1146       { NULL, }
1147     };
1148
1149   g_type_init ();
1150
1151   g_typelib_check_sanity ();
1152
1153   context = g_option_context_new ("");
1154   g_option_context_add_main_entries (context, options, NULL);
1155   g_option_context_parse (context, &argc, &argv, &error);
1156
1157   if (!input) 
1158     { 
1159       g_fprintf (stderr, "no input files\n"); 
1160       
1161       return 1;
1162     }
1163
1164   for (i = 0; input[i]; i++)
1165     {
1166       GModule *dlhandle = NULL;
1167       const guchar *typelib;
1168       gsize len;
1169
1170       if (raw)
1171         {
1172           if (!g_file_get_contents (input[i], (gchar **)&typelib, &len, &error))
1173             {
1174               g_fprintf (stderr, "failed to read '%s': %s\n", 
1175                          input[i], error->message);
1176               g_clear_error (&error);
1177               continue;
1178             }
1179         }
1180       else
1181         {
1182           typelib = load_typelib (input[i], &dlhandle, &len);
1183           if (!typelib)
1184             {
1185               g_fprintf (stderr, "failed to load typelib from '%s'\n", 
1186                          input[i]);
1187               continue;
1188             }
1189         }
1190
1191       if (input[i + 1] && output)
1192         needs_prefix = TRUE;
1193       else
1194         needs_prefix = FALSE;
1195
1196       data = g_typelib_new_from_const_memory (typelib, len);
1197       {
1198         GError *error = NULL;
1199         if (!g_typelib_validate (data, &error)) {
1200           g_printerr ("typelib not valid: %s\n", error->message);
1201           g_clear_error (&error);
1202         }
1203       }
1204       g_irepository_register (g_irepository_get_default (), data);
1205       write_repository (g_irepository_get_default (), needs_prefix);
1206       g_irepository_unregister (g_irepository_get_default (),
1207                                 g_typelib_get_namespace (data));
1208
1209       if (dlhandle)
1210         {
1211           g_module_close (dlhandle);
1212           dlhandle = NULL;
1213         }
1214
1215       /* when writing to stdout, stop after the first module */
1216       if (input[i + 1] && !output)
1217         {
1218           g_fprintf (stderr, "warning, %d modules omitted\n",
1219                      g_strv_length (input) - 1);
1220
1221           break;
1222         }
1223     }
1224       
1225   return 0;
1226 }