Bug 560404 – Prefix types when resolving aliases in included modules
[gnome.gobject-introspection] / girepository / girparser.c
1 /* GObject introspection: A parser for the XML GIR format
2  *
3  * Copyright (C) 2008 Philip Van Hoof
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdio.h>
24
25 #include <glib.h>
26 #include "girparser.h"
27 #include "girmodule.h"
28 #include "girnode.h"
29 #include "gtypelib.h"
30
31 typedef enum
32 {
33   STATE_START,    
34   STATE_END,        
35   STATE_REPOSITORY, 
36   STATE_INCLUDE,  
37   STATE_NAMESPACE,  
38   STATE_ENUM,      /* 5 */    
39   STATE_BITFIELD,  
40   STATE_FUNCTION,   
41   STATE_FUNCTION_RETURN, 
42   STATE_FUNCTION_PARAMETERS,
43   STATE_FUNCTION_PARAMETER,  /* 10 */
44   STATE_CLASS,  
45   STATE_CLASS_FIELD,
46   STATE_CLASS_PROPERTY,
47   STATE_INTERFACE,
48   STATE_INTERFACE_PROPERTY,   /* 15 */
49   STATE_INTERFACE_FIELD,
50   STATE_IMPLEMENTS, 
51   STATE_REQUIRES,
52   STATE_BOXED,  
53   STATE_BOXED_FIELD, /* 20 */
54   STATE_STRUCT,   
55   STATE_STRUCT_FIELD,
56   STATE_ERRORDOMAIN, 
57   STATE_UNION,
58   STATE_UNION_FIELD, /* 25 */
59   STATE_NAMESPACE_CONSTANT, 
60   STATE_CLASS_CONSTANT, 
61   STATE_INTERFACE_CONSTANT,
62   STATE_ALIAS,
63   STATE_TYPE
64 } ParseState;
65
66 typedef struct _ParseContext ParseContext;
67 struct _ParseContext
68 {
69   ParseState state;
70   ParseState prev_state;
71
72   const char * const*includes;
73   
74   GList *modules;
75   GList *include_modules;
76   gboolean prefix_aliases;
77   GList *dependencies;
78   GHashTable *aliases;
79   GHashTable *disguised_structures;
80
81   const char *namespace;
82   GIrModule *current_module;
83   GIrNode *current_node;
84   GIrNode *current_typed;
85   gboolean is_varargs;
86   GList *type_stack;
87   GList *type_parameters;
88   int type_depth;
89 };
90
91 static void start_element_handler (GMarkupParseContext *context,
92                                    const gchar         *element_name,
93                                    const gchar        **attribute_names,
94                                    const gchar        **attribute_values,
95                                    gpointer             user_data,
96                                    GError             **error);
97 static void end_element_handler   (GMarkupParseContext *context,
98                                    const gchar         *element_name,
99                                    gpointer             user_data,
100                                    GError             **error);
101 static void text_handler          (GMarkupParseContext *context,
102                                    const gchar         *text,
103                                    gsize                text_len,
104                                    gpointer             user_data,
105                                    GError             **error);
106 static void cleanup               (GMarkupParseContext *context,
107                                    GError              *error,
108                                    gpointer             user_data);
109
110 static GMarkupParser parser = 
111 {
112   start_element_handler,
113   end_element_handler,
114   text_handler,
115   NULL,
116   cleanup
117 };
118
119 static gboolean
120 start_alias (GMarkupParseContext *context,
121              const gchar         *element_name,
122              const gchar        **attribute_names,
123              const gchar        **attribute_values,
124              ParseContext        *ctx,
125              GError             **error);
126
127 static const gchar *find_attribute (const gchar  *name, 
128                                     const gchar **attribute_names,
129                                     const gchar **attribute_values);
130
131 static void
132 firstpass_start_element_handler (GMarkupParseContext *context,
133                                  const gchar         *element_name,
134                                  const gchar        **attribute_names,
135                                  const gchar        **attribute_values,
136                                  gpointer             user_data,
137                                  GError             **error)
138 {
139   ParseContext *ctx = user_data;
140
141   if (strcmp (element_name, "alias") == 0) 
142     {
143       start_alias (context, element_name, attribute_names, attribute_values,
144                    ctx, error);
145     }
146   else if (strcmp (element_name, "record") == 0)
147     {
148       const gchar *name;
149       const gchar *disguised;
150
151       name = find_attribute ("name", attribute_names, attribute_values);
152       disguised = find_attribute ("disguised", attribute_names, attribute_values);
153
154       if (disguised && strcmp (disguised, "1") == 0)
155         {
156           char *key;
157
158           if (ctx->prefix_aliases)
159             {
160               key = g_strdup_printf ("%s.%s", ctx->namespace, name);
161             }
162           else
163             {
164               key = g_strdup (name);
165             }
166
167           g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
168         }
169     }
170 }
171
172 static void
173 firstpass_end_element_handler (GMarkupParseContext *context,
174                                const gchar         *element_name,
175                                gpointer             user_data,
176                                GError             **error)
177 {
178 }
179
180 static GMarkupParser firstpass_parser = 
181 {
182   firstpass_start_element_handler,
183   firstpass_end_element_handler,
184   NULL,
185   NULL,
186   NULL,
187 };
188
189 static char *
190 locate_gir (const char *name, const char *version, const char * const* extra_paths)
191 {
192   const gchar *const *datadirs;
193   const gchar *const *dir;
194   char *girname;
195   char *path = NULL;
196       
197   datadirs = g_get_system_data_dirs ();
198       
199   girname = g_strdup_printf ("%s-%s.gir", name, version);
200   
201   if (extra_paths != NULL)
202     {
203       for (dir = extra_paths; *dir; dir++) 
204         {
205           path = g_build_filename (*dir, girname, NULL);
206           if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
207             return path;
208           g_free (path);
209           path = NULL;
210         }
211     }
212   for (dir = datadirs; *dir; dir++) 
213     {
214       path = g_build_filename (*dir, "gir", girname, NULL);
215       if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
216         return path;
217       g_free (path);
218       path = NULL;
219     }
220   g_free (girname);
221   return path;
222 }
223
224 #define MISSING_ATTRIBUTE(ctx,error,element,attribute)                          \
225   do {                                                                          \
226     int line_number, char_number;                                                \
227     g_markup_parse_context_get_position (context, &line_number, &char_number);  \
228     g_set_error (error,                                                         \
229                  G_MARKUP_ERROR,                                                \
230                  G_MARKUP_ERROR_INVALID_CONTENT,                                \
231                  "Line %d, character %d: The attribute '%s' on the element '%s' must be specified",    \
232                  line_number, char_number, attribute, element);         \
233   } while (0)
234
235 static void
236 backtrace_stderr (void)
237 {
238 #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
239   void *array[50];
240   int size;
241   char **strings;
242   size_t i;
243
244   size = backtrace (array, 50);
245   strings = (char**) backtrace_symbols (array, size);
246
247   fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size);
248
249   for (i = 0; i < size; i++)
250     fprintf (stderr, "%s\n", strings[i]);
251
252   fprintf (stderr, "--- END BACKTRACE ---\n", size);
253
254   free (strings);
255 #endif
256 }
257
258
259 static const gchar *
260 find_attribute (const gchar  *name, 
261                 const gchar **attribute_names,
262                 const gchar **attribute_values)
263 {
264   gint i;
265   
266   for (i = 0; attribute_names[i] != NULL; i++)
267     if (strcmp (attribute_names[i], name) == 0)
268       return attribute_values[i];
269   
270   return 0;
271 }
272
273 static void
274 state_switch (ParseContext *ctx, ParseState newstate)
275 {
276   g_debug ("State: %d", newstate);
277   ctx->prev_state = ctx->state;
278   ctx->state = newstate;
279 }
280
281 static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
282                                           gboolean in_gobject);
283
284 typedef struct {
285   const gchar *str;
286   gint tag;
287   gboolean pointer;
288 } BasicTypeInfo;
289
290 static BasicTypeInfo basic_types[] = {
291     { "none",     GI_TYPE_TAG_VOID,    0 },
292     { "any",      GI_TYPE_TAG_VOID,    1 },
293
294     { "bool",     GI_TYPE_TAG_BOOLEAN, 0 },
295     { "char",     GI_TYPE_TAG_INT8,    0 },
296     { "int8",     GI_TYPE_TAG_INT8,    0 },
297     { "uint8",    GI_TYPE_TAG_UINT8,   0 },
298     { "int16",    GI_TYPE_TAG_INT16,   0 },
299     { "uint16",   GI_TYPE_TAG_UINT16,  0 },
300     { "int32",    GI_TYPE_TAG_INT32,   0 },
301     { "uint32",   GI_TYPE_TAG_UINT32,  0 },
302     { "int64",    GI_TYPE_TAG_INT64,   0 },
303     { "uint64",   GI_TYPE_TAG_UINT64,  0 },
304     { "int",      GI_TYPE_TAG_INT,     0 },
305     { "uint",     GI_TYPE_TAG_UINT,    0 },
306     { "long",     GI_TYPE_TAG_LONG,    0 },
307     { "ulong",    GI_TYPE_TAG_ULONG,   0 },
308     { "ssize_t",  GI_TYPE_TAG_SSIZE,   0 },
309     { "ssize",    GI_TYPE_TAG_SSIZE,   0 },
310     { "size_t",   GI_TYPE_TAG_SIZE,    0 },
311     { "size",     GI_TYPE_TAG_SIZE,    0 },
312     { "float",    GI_TYPE_TAG_FLOAT,   0 },
313     { "double",   GI_TYPE_TAG_DOUBLE,  0 },
314     { "time_t",   GI_TYPE_TAG_TIME_T,  0 },
315     { "GType",    GI_TYPE_TAG_GTYPE,   0 },
316     { "utf8",     GI_TYPE_TAG_UTF8,    1 },  
317     { "filename", GI_TYPE_TAG_FILENAME,1 },
318 };  
319
320 static const BasicTypeInfo *
321 parse_basic (const char *str)
322 {
323   gint i;
324   gint n_basic = G_N_ELEMENTS (basic_types);
325   
326   for (i = 0; i < n_basic; i++)
327     {
328       if (g_str_has_prefix (str, basic_types[i].str))
329         return &(basic_types[i]);
330     }  
331   return NULL;
332 }
333
334 static GIrNodeType *
335 parse_type_internal (const gchar *str, char **next, gboolean in_glib,
336                      gboolean in_gobject)
337 {
338   const BasicTypeInfo *basic;  
339   GIrNodeType *type;
340   char *temporary_type = NULL;
341   
342   type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
343   
344   type->unparsed = g_strdup (str);
345
346   /* See comment below on GLib.List handling */
347   if (in_gobject && strcmp (str, "Type") == 0) 
348     {
349       temporary_type = g_strdup ("GLib.Type");
350       str = temporary_type;
351     }
352   
353   basic = parse_basic (str);
354   if (basic != NULL)
355     {
356       type->is_basic = TRUE;
357       type->tag = basic->tag;
358       type->is_pointer = basic->pointer;
359
360       str += strlen(basic->str);
361     }
362   else if (in_glib)
363     {
364       /* If we're inside GLib, handle "List" etc. by prefixing with
365        * "GLib." so the parsing code below doesn't have to get more
366        * special. 
367        */
368       if (g_str_has_prefix (str, "List<") ||
369           strcmp (str, "List") == 0)
370         {
371           temporary_type = g_strdup_printf ("GLib.List%s", str + 4);
372           str = temporary_type;
373         }
374       else if (g_str_has_prefix (str, "SList<") ||
375           strcmp (str, "SList") == 0)
376         {
377           temporary_type = g_strdup_printf ("GLib.SList%s", str + 5);
378           str = temporary_type;
379         }
380       else if (g_str_has_prefix (str, "HashTable<") ||
381           strcmp (str, "HashTable") == 0)
382         {
383           temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9);
384           str = temporary_type;
385         }
386       else if (g_str_has_prefix (str, "Error<") ||
387           strcmp (str, "Error") == 0)
388         {
389           temporary_type = g_strdup_printf ("GLib.Error%s", str + 5);
390           str = temporary_type;
391         }
392     }
393
394   if (basic != NULL)
395     /* found a basic type */;
396   else if (g_str_has_prefix (str, "GLib.List") ||
397            g_str_has_prefix (str, "GLib.SList"))
398     {
399       str += strlen ("GLib.");
400       if (g_str_has_prefix (str, "List"))
401         {
402           type->tag = GI_TYPE_TAG_GLIST;
403           type->is_glist = TRUE;
404           type->is_pointer = TRUE;
405           str += strlen ("List");
406         }
407       else
408         {
409           type->tag = GI_TYPE_TAG_GSLIST;
410           type->is_gslist = TRUE;
411           type->is_pointer = TRUE;
412           str += strlen ("SList");
413         }
414     }
415   else if (g_str_has_prefix (str, "GLib.HashTable"))
416     {
417       str += strlen ("GLib.");
418
419       type->tag = GI_TYPE_TAG_GHASH;
420       type->is_ghashtable = TRUE;
421       type->is_pointer = TRUE;
422       str += strlen ("HashTable");
423     }
424   else if (g_str_has_prefix (str, "GLib.Error"))
425     {
426       str += strlen ("GLib.");
427
428       type->tag = GI_TYPE_TAG_ERROR;
429       type->is_error = TRUE;
430       type->is_pointer = TRUE;
431       str += strlen ("Error");
432       
433       if (*str == '<')
434         {
435           (str)++;
436           char *tmp, *end;
437           
438           end = strchr (str, '>');
439           tmp = g_strndup (str, end - str);
440           type->errors = g_strsplit (tmp, ",", 0);
441           g_free (tmp);
442
443           str = end;
444         }
445     }
446   else 
447     {
448       type->tag = GI_TYPE_TAG_INTERFACE;
449       type->is_interface = TRUE; 
450       const char *start = str;
451
452       /* must be an interface type */
453       while (g_ascii_isalnum (*str) || 
454              *str == '.' || 
455              *str == '-' || 
456              *str == '_' ||
457              *str == ':')
458         (str)++;
459
460       type->interface = g_strndup (start, str - start);
461     }
462   
463   if (next)
464     *next = (char*)str;
465   g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR);
466   g_free (temporary_type);
467   return type;
468
469 /* error: */
470   g_ir_node_free ((GIrNode *)type);
471   g_free (temporary_type);  
472   return NULL;
473 }
474
475 static const char *
476 resolve_aliases (ParseContext *ctx, const gchar *type)
477 {
478   gpointer orig;
479   gpointer value;
480   GSList *seen_values = NULL;
481   const char *lookup;
482   char *prefixed;
483
484   /* If we are in an included module, then we need to qualify the
485    * names of types before resolving them, since they will have
486    * been stored in the aliases qualified.
487    */
488   if (ctx->prefix_aliases && strchr (type, '.') == NULL)
489     {
490       prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
491       lookup = prefixed;
492     }
493   else
494     lookup = type;
495
496   seen_values = g_slist_prepend (seen_values, (char*)lookup);
497   while (g_hash_table_lookup_extended (ctx->aliases, lookup, &orig, &value))
498     {
499       g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
500       lookup = value;
501       if (g_slist_find_custom (seen_values, lookup,
502                                (GCompareFunc)strcmp) != NULL)
503         break;
504       seen_values = g_slist_prepend (seen_values, (gchar*)lookup);
505     }
506   g_slist_free (seen_values);
507
508   if (lookup == prefixed)
509     lookup = type;
510   
511   g_free (prefixed);
512   
513   return lookup;
514 }
515
516 static GIrNodeType *
517 parse_type (ParseContext *ctx, const gchar *type)
518 {
519   GIrNodeType *node;
520   const BasicTypeInfo *basic;
521   gboolean in_glib, in_gobject;
522
523   in_glib = strcmp (ctx->namespace, "GLib") == 0;
524   in_gobject = strcmp (ctx->namespace, "GObject") == 0;
525
526   /* Do not search aliases for basic types */
527   basic = parse_basic (type);
528   if (basic == NULL)
529     type = resolve_aliases (ctx, type);
530
531   node = parse_type_internal (type, NULL, in_glib, in_gobject);
532   if (node)
533     g_debug ("Parsed type: %s => %d", type, node->tag);
534   else
535     g_critical ("Failed to parse type: '%s'", type);
536
537   return node;
538 }
539
540 static gboolean
541 start_glib_boxed (GMarkupParseContext *context,
542                   const gchar         *element_name,
543                   const gchar        **attribute_names,
544                   const gchar        **attribute_values,
545                   ParseContext        *ctx,
546                   GError             **error)
547 {
548   const gchar *name;
549   const gchar *typename;
550   const gchar *typeinit;
551   const gchar *deprecated;
552   GIrNodeBoxed *boxed;
553
554   if (!(strcmp (element_name, "glib:boxed") == 0 &&
555         ctx->state == STATE_NAMESPACE))
556     return FALSE;
557
558   name = find_attribute ("glib:name", attribute_names, attribute_values);
559   typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
560   typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
561   deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
562   
563   if (name == NULL)
564     {
565       MISSING_ATTRIBUTE (context, error, element_name, "glib:name");
566       return FALSE;
567     }
568   else if (typename == NULL)
569     {
570       MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
571       return FALSE;
572     }
573   else if (typeinit == NULL)
574     {
575       MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
576       return FALSE;
577     }
578
579   boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED);
580           
581   ((GIrNode *)boxed)->name = g_strdup (name);
582   boxed->gtype_name = g_strdup (typename);
583   boxed->gtype_init = g_strdup (typeinit);
584   if (deprecated)
585     boxed->deprecated = TRUE;
586   else
587     boxed->deprecated = FALSE;
588           
589   ctx->current_node = (GIrNode *)boxed;
590   ctx->current_module->entries = 
591     g_list_append (ctx->current_module->entries, boxed);
592   
593   state_switch (ctx, STATE_BOXED);
594
595   return TRUE;
596 }
597
598 static gboolean
599 start_function (GMarkupParseContext *context,
600                 const gchar         *element_name,
601                 const gchar        **attribute_names,
602                 const gchar        **attribute_values,
603                 ParseContext        *ctx,
604                 GError             **error)
605 {
606   const gchar *name;
607   const gchar *symbol;
608   const gchar *deprecated;
609   const gchar *throws;
610   GIrNodeFunction *function;
611   gboolean found = FALSE;
612   
613   switch (ctx->state)
614     {
615     case STATE_NAMESPACE:
616       found = (strcmp (element_name, "function") == 0 ||
617                strcmp (element_name, "callback") == 0);
618       break;
619     case STATE_CLASS:
620     case STATE_BOXED:
621     case STATE_STRUCT:
622     case STATE_UNION:
623       found = strcmp (element_name, "constructor") == 0;
624       /* fallthrough */
625     case STATE_INTERFACE:
626       found = (found ||
627                strcmp (element_name, "method") == 0 ||
628                strcmp (element_name, "callback") == 0);
629       break;
630     default:
631       break;
632     }
633
634   if (!found)
635     return FALSE;
636
637   name = find_attribute ("name", attribute_names, attribute_values);
638   symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
639   deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
640   throws = find_attribute ("throws", attribute_names, attribute_values);
641       
642   if (name == NULL)
643     {
644       MISSING_ATTRIBUTE (context, error, element_name, "name");
645       return FALSE;
646     }
647   else if (strcmp (element_name, "callback") != 0 && symbol == NULL)
648     {
649       MISSING_ATTRIBUTE (context, error, element_name, "c:identifier");
650       return FALSE;
651     }
652
653   function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION);
654       
655   ((GIrNode *)function)->name = g_strdup (name);
656   function->symbol = g_strdup (symbol);
657   function->parameters = NULL;
658   if (deprecated)
659     function->deprecated = TRUE;
660   else
661     function->deprecated = FALSE;
662   
663   if (strcmp (element_name, "method") == 0 ||
664       strcmp (element_name, "constructor") == 0)
665     {
666       function->is_method = TRUE;
667       
668       if (strcmp (element_name, "constructor") == 0)
669         function->is_constructor = TRUE;
670       else
671         function->is_constructor = FALSE;
672     }
673   else
674     {
675       function->is_method = FALSE;
676       function->is_setter = FALSE;
677       function->is_getter = FALSE;
678       function->is_constructor = FALSE;
679       if (strcmp (element_name, "callback") == 0)
680         ((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
681     }
682
683   if (throws && strcmp (throws, "1") == 0)
684     function->throws = TRUE;
685   else
686     function->throws = FALSE;
687
688   if (ctx->current_node == NULL)
689     {
690       ctx->current_module->entries = 
691         g_list_append (ctx->current_module->entries, function);       
692     }
693   else
694     switch (ctx->current_node->type)
695       {
696       case G_IR_NODE_INTERFACE:
697       case G_IR_NODE_OBJECT:
698         {
699           GIrNodeInterface *iface;
700           
701           iface = (GIrNodeInterface *)ctx->current_node;
702           iface->members = g_list_append (iface->members, function);
703         }
704         break;
705       case G_IR_NODE_BOXED:
706         {
707           GIrNodeBoxed *boxed;
708           
709           boxed = (GIrNodeBoxed *)ctx->current_node;
710           boxed->members = g_list_append (boxed->members, function);
711         }
712         break;
713       case G_IR_NODE_STRUCT:
714         {
715           GIrNodeStruct *struct_;
716           
717           struct_ = (GIrNodeStruct *)ctx->current_node;
718           struct_->members = g_list_append (struct_->members, function);                }
719         break;
720       case G_IR_NODE_UNION:
721         {
722           GIrNodeUnion *union_;
723           
724           union_ = (GIrNodeUnion *)ctx->current_node;
725           union_->members = g_list_append (union_->members, function);
726         }
727         break;
728       default:
729         g_assert_not_reached ();
730       }
731   
732   ctx->current_node = (GIrNode *)function;
733   state_switch (ctx, STATE_FUNCTION);
734   
735   return TRUE;
736 }
737
738 static void
739 parse_param_transfer (GIrNodeParam *param, const gchar *transfer)
740 {
741   if (transfer == NULL)
742   {
743     g_warning ("required attribute 'transfer-ownership' missing");
744   }
745   else if (strcmp (transfer, "none") == 0)
746     {
747       param->transfer = FALSE;
748       param->shallow_transfer = FALSE;
749     }
750   else if (strcmp (transfer, "container") == 0)
751     {
752       param->transfer = FALSE;
753       param->shallow_transfer = TRUE;
754     }
755   else if (strcmp (transfer, "full") == 0)
756     {
757       param->transfer = TRUE;
758       param->shallow_transfer = FALSE;
759     }
760   else
761     {
762       g_warning ("Unknown transfer-ownership value: %s", transfer);
763     }
764 }
765
766 static gboolean
767 start_parameter (GMarkupParseContext *context,
768                  const gchar         *element_name,
769                  const gchar        **attribute_names,
770                  const gchar        **attribute_values,
771                  ParseContext        *ctx,
772                  GError             **error)
773 {
774   const gchar *name;
775   const gchar *direction;
776   const gchar *retval;
777   const gchar *dipper;
778   const gchar *optional;
779   const gchar *allow_none;
780   const gchar *transfer;
781   GIrNodeParam *param;
782       
783   if (!(strcmp (element_name, "parameter") == 0 &&
784         ctx->state == STATE_FUNCTION_PARAMETERS))
785     return FALSE;
786
787   name = find_attribute ("name", attribute_names, attribute_values);
788   direction = find_attribute ("direction", attribute_names, attribute_values);
789   retval = find_attribute ("retval", attribute_names, attribute_values);
790   dipper = find_attribute ("dipper", attribute_names, attribute_values);
791   optional = find_attribute ("optional", attribute_names, attribute_values);
792   allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
793   transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
794
795   if (name == NULL)
796     name = "unknown";
797
798   param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
799
800   ctx->current_typed = (GIrNode*) param;
801   ctx->current_typed->name = g_strdup (name);
802
803   state_switch (ctx, STATE_FUNCTION_PARAMETER);
804
805   if (direction && strcmp (direction, "out") == 0)
806     {
807       param->in = FALSE;
808       param->out = TRUE;
809     }
810   else if (direction && strcmp (direction, "inout") == 0)
811     {
812       param->in = TRUE;
813       param->out = TRUE;
814     }
815   else
816     {
817       param->in = TRUE;
818       param->out = FALSE;
819     }
820
821   if (retval && strcmp (retval, "1") == 0)
822     param->retval = TRUE;
823   else
824     param->retval = FALSE;
825
826   if (dipper && strcmp (dipper, "1") == 0)
827     param->dipper = TRUE;
828   else
829     param->dipper = FALSE;
830
831   if (optional && strcmp (optional, "1") == 0)
832     param->optional = TRUE;
833   else
834     param->optional = FALSE;
835
836   if (allow_none && strcmp (allow_none, "1") == 0)
837     param->allow_none = TRUE;
838   else
839     param->allow_none = FALSE;
840
841   parse_param_transfer (param, transfer);
842
843   ((GIrNode *)param)->name = g_strdup (name);
844           
845   switch (ctx->current_node->type)
846     {
847     case G_IR_NODE_FUNCTION:
848     case G_IR_NODE_CALLBACK:
849       {
850         GIrNodeFunction *func;
851
852         func = (GIrNodeFunction *)ctx->current_node;
853         func->parameters = g_list_append (func->parameters, param);
854       }
855       break;
856     case G_IR_NODE_SIGNAL:
857       {
858         GIrNodeSignal *signal;
859
860         signal = (GIrNodeSignal *)ctx->current_node;
861         signal->parameters = g_list_append (signal->parameters, param);
862       }
863       break;
864     case G_IR_NODE_VFUNC:
865       {
866         GIrNodeVFunc *vfunc;
867                 
868         vfunc = (GIrNodeVFunc *)ctx->current_node;
869         vfunc->parameters = g_list_append (vfunc->parameters, param);
870       }
871       break;
872     default:
873       g_assert_not_reached ();
874     }
875
876   return TRUE;
877 }
878
879 static gboolean
880 start_field (GMarkupParseContext *context,
881              const gchar         *element_name,
882              const gchar        **attribute_names,
883              const gchar        **attribute_values,
884              ParseContext        *ctx,
885              GError             **error)
886 {
887   const gchar *name;
888   const gchar *readable;
889   const gchar *writable;
890   const gchar *bits;
891   const gchar *branch;
892   GIrNodeField *field;
893
894   switch (ctx->state)
895     {
896     case STATE_CLASS:
897     case STATE_BOXED:
898     case STATE_STRUCT:
899     case STATE_UNION:
900     case STATE_INTERFACE:
901       break;
902     default:
903       return FALSE;
904     }
905   
906   if (strcmp (element_name, "field") != 0)
907     return FALSE;
908   
909   name = find_attribute ("name", attribute_names, attribute_values);
910   readable = find_attribute ("readable", attribute_names, attribute_values);
911   writable = find_attribute ("writable", attribute_names, attribute_values);
912   bits = find_attribute ("bits", attribute_names, attribute_values);
913   branch = find_attribute ("branch", attribute_names, attribute_values);
914   
915   if (name == NULL)
916     {
917       MISSING_ATTRIBUTE (context, error, element_name, "name");
918       return FALSE;
919     }
920
921   field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD);
922   ctx->current_typed = (GIrNode*) field;
923   ((GIrNode *)field)->name = g_strdup (name);
924   /* Fields are assumed to be read-only.
925    * (see also girwriter.py and generate.c)
926    */
927   field->readable = readable == NULL || strcmp (readable, "0") == 0;
928   field->writable = writable != NULL && strcmp (writable, "1") == 0;
929   
930   if (bits)
931     field->bits = atoi (bits);
932   else
933     field->bits = 0;
934   
935   switch (ctx->current_node->type)
936     {
937     case G_IR_NODE_OBJECT:
938       {
939         GIrNodeInterface *iface;
940         
941         iface = (GIrNodeInterface *)ctx->current_node;
942         iface->members = g_list_append (iface->members, field);
943         state_switch (ctx, STATE_CLASS_FIELD);
944       }
945       break;
946     case G_IR_NODE_INTERFACE:
947       {
948         GIrNodeInterface *iface;
949         
950         iface = (GIrNodeInterface *)ctx->current_node;
951         iface->members = g_list_append (iface->members, field);
952         state_switch (ctx, STATE_INTERFACE_FIELD);
953       }
954       break;
955     case G_IR_NODE_BOXED:
956       {
957         GIrNodeBoxed *boxed;
958         
959         boxed = (GIrNodeBoxed *)ctx->current_node;
960                 boxed->members = g_list_append (boxed->members, field);
961                 state_switch (ctx, STATE_BOXED_FIELD);
962       }
963       break;
964     case G_IR_NODE_STRUCT:
965       {
966         GIrNodeStruct *struct_;
967         
968         struct_ = (GIrNodeStruct *)ctx->current_node;
969         struct_->members = g_list_append (struct_->members, field);
970         state_switch (ctx, STATE_STRUCT_FIELD);
971       }
972       break;
973     case G_IR_NODE_UNION:
974       {
975         GIrNodeUnion *union_;
976         
977         union_ = (GIrNodeUnion *)ctx->current_node;
978         union_->members = g_list_append (union_->members, field);
979         if (branch)
980           {
981             GIrNodeConstant *constant;
982             
983             constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
984             ((GIrNode *)constant)->name = g_strdup (name);
985             constant->value = g_strdup (branch);          
986             constant->type = union_->discriminator_type;
987             constant->deprecated = FALSE;
988             
989             union_->discriminators = g_list_append (union_->discriminators, constant);
990           }
991         state_switch (ctx, STATE_UNION_FIELD);
992       }
993       break;
994     default:
995       g_assert_not_reached ();
996     }
997   
998   return TRUE;
999 }
1000
1001 static gboolean
1002 start_alias (GMarkupParseContext *context,
1003              const gchar         *element_name,
1004              const gchar        **attribute_names,
1005              const gchar        **attribute_values,
1006              ParseContext        *ctx,
1007              GError             **error)
1008 {
1009   const gchar *name;
1010   const gchar *target;
1011   char *key;
1012   char *value;
1013
1014   name = find_attribute ("name", attribute_names, attribute_values);
1015   if (name == NULL)
1016     {
1017       MISSING_ATTRIBUTE (context, error, element_name, "name");
1018       return FALSE;
1019     }
1020
1021   target = find_attribute ("target", attribute_names, attribute_values);
1022   if (name == NULL)
1023     {
1024       MISSING_ATTRIBUTE (context, error, element_name, "target");
1025       return FALSE;
1026     }
1027
1028   value = g_strdup (target);
1029   if (ctx->prefix_aliases)
1030     {
1031       key = g_strdup_printf ("%s.%s", ctx->namespace, name);
1032       if (!strchr (target, '.'))
1033         {
1034           const BasicTypeInfo *basic = parse_basic (target);
1035           if (!basic)
1036             {
1037               g_free (value);
1038               /* For non-basic types, re-qualify the interface */
1039               value = g_strdup_printf ("%s.%s", ctx->namespace, target);
1040             }
1041         }
1042     }
1043   else
1044     {
1045       key = g_strdup (name);
1046     }
1047   g_hash_table_insert (ctx->aliases, key, value);
1048
1049   return TRUE;
1050 }
1051
1052 static gboolean
1053 start_enum (GMarkupParseContext *context,
1054              const gchar         *element_name,
1055              const gchar        **attribute_names,
1056              const gchar        **attribute_values,
1057              ParseContext        *ctx,
1058              GError             **error)
1059 {
1060   if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
1061       (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))
1062     {
1063       const gchar *name;
1064       const gchar *typename;
1065       const gchar *typeinit;
1066       const gchar *deprecated;
1067       
1068       name = find_attribute ("name", attribute_names, attribute_values);
1069       typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1070       typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1071       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1072       
1073       if (name == NULL)
1074         MISSING_ATTRIBUTE (context, error, element_name, "name");
1075       else 
1076         {             
1077           GIrNodeEnum *enum_;
1078           
1079           if (strcmp (element_name, "enumeration") == 0)
1080             enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM);
1081           else
1082             enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS);
1083           ((GIrNode *)enum_)->name = g_strdup (name);
1084           enum_->gtype_name = g_strdup (typename);
1085           enum_->gtype_init = g_strdup (typeinit);
1086           if (deprecated)
1087             enum_->deprecated = TRUE;
1088           else
1089             enum_->deprecated = FALSE;
1090
1091           ctx->current_node = (GIrNode *) enum_;
1092           ctx->current_module->entries = 
1093             g_list_append (ctx->current_module->entries, enum_);              
1094           
1095           state_switch (ctx, STATE_ENUM);
1096         }
1097       
1098       return TRUE;
1099     }
1100   return FALSE;
1101 }
1102
1103 static gboolean
1104 start_property (GMarkupParseContext *context,
1105                 const gchar         *element_name,
1106                 const gchar        **attribute_names,
1107                 const gchar        **attribute_values,
1108                 ParseContext        *ctx,
1109                 GError             **error)
1110 {
1111   if (strcmp (element_name, "property") == 0 &&
1112       (ctx->state == STATE_CLASS ||
1113        ctx->state == STATE_INTERFACE))
1114     {
1115       const gchar *name;
1116       const gchar *readable;
1117       const gchar *writable;
1118       const gchar *construct;
1119       const gchar *construct_only;
1120       
1121       name = find_attribute ("name", attribute_names, attribute_values);
1122       readable = find_attribute ("readable", attribute_names, attribute_values);
1123       writable = find_attribute ("writable", attribute_names, attribute_values);
1124       construct = find_attribute ("construct", attribute_names, attribute_values);
1125       construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
1126       
1127       if (name == NULL)
1128         MISSING_ATTRIBUTE (context, error, element_name, "name");
1129       else 
1130         {             
1131           GIrNodeProperty *property;
1132           GIrNodeInterface *iface;
1133           
1134           property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
1135           ctx->current_typed = (GIrNode*) property;
1136
1137           ((GIrNode *)property)->name = g_strdup (name);
1138           
1139           /* Assume properties are readable */
1140           if (readable == NULL || strcmp (readable, "1") == 0)
1141             property->readable = TRUE;
1142           else
1143             property->readable = FALSE;
1144           if (writable && strcmp (writable, "1") == 0)
1145             property->writable = TRUE;
1146           else
1147             property->writable = FALSE;
1148           if (construct && strcmp (construct, "1") == 0)
1149             property->construct = TRUE;
1150           else
1151             property->construct = FALSE;
1152           if (construct_only && strcmp (construct_only, "1") == 0)
1153             property->construct_only = TRUE;
1154           else
1155             property->construct_only = FALSE;
1156
1157           iface = (GIrNodeInterface *)ctx->current_node;
1158           iface->members = g_list_append (iface->members, property);
1159
1160           if (ctx->state == STATE_CLASS)
1161             state_switch (ctx, STATE_CLASS_PROPERTY);
1162           else if (ctx->state == STATE_INTERFACE)
1163             state_switch (ctx, STATE_INTERFACE_PROPERTY);
1164           else
1165             g_assert_not_reached ();
1166         }
1167       
1168       return TRUE;
1169     }
1170   return FALSE;
1171 }
1172
1173 static gint
1174 parse_value (const gchar *str)
1175 {
1176   gchar *shift_op;
1177  
1178   /* FIXME just a quick hack */
1179   shift_op = strstr (str, "<<");
1180
1181   if (shift_op)
1182     {
1183       gint base, shift;
1184
1185       base = strtol (str, NULL, 10);
1186       shift = strtol (shift_op + 3, NULL, 10);
1187       
1188       return base << shift;
1189     }
1190   else
1191     return strtol (str, NULL, 10);
1192
1193   return 0;
1194 }
1195
1196 static gboolean
1197 start_member (GMarkupParseContext *context,
1198               const gchar         *element_name,
1199               const gchar        **attribute_names,
1200               const gchar        **attribute_values,
1201               ParseContext        *ctx,
1202               GError             **error)
1203 {
1204   if (strcmp (element_name, "member") == 0 &&
1205       ctx->state == STATE_ENUM)
1206     {
1207       const gchar *name;
1208       const gchar *value;
1209       const gchar *deprecated;
1210       
1211       name = find_attribute ("name", attribute_names, attribute_values);
1212       value = find_attribute ("value", attribute_names, attribute_values);
1213       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1214       
1215       if (name == NULL)
1216         MISSING_ATTRIBUTE (context, error, element_name, "name");
1217       else 
1218         {             
1219           GIrNodeEnum *enum_;
1220           GIrNodeValue *value_;
1221
1222           value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
1223
1224           ((GIrNode *)value_)->name = g_strdup (name);
1225           
1226           value_->value = parse_value (value);
1227           
1228           if (deprecated)
1229             value_->deprecated = TRUE;
1230           else
1231             value_->deprecated = FALSE;
1232
1233           enum_ = (GIrNodeEnum *)ctx->current_node;
1234           enum_->values = g_list_append (enum_->values, value_);
1235         }
1236       
1237       return TRUE;
1238     }
1239   return FALSE;
1240 }
1241
1242 static gboolean
1243 start_constant (GMarkupParseContext *context,
1244                 const gchar         *element_name,
1245                 const gchar        **attribute_names,
1246                 const gchar        **attribute_values,
1247                 ParseContext        *ctx,
1248                 GError             **error)
1249 {
1250   if (strcmp (element_name, "constant") == 0 &&
1251       (ctx->state == STATE_NAMESPACE ||
1252        ctx->state == STATE_CLASS ||
1253        ctx->state == STATE_INTERFACE))
1254     {
1255       const gchar *name;
1256       const gchar *value;
1257       const gchar *deprecated;
1258       
1259       name = find_attribute ("name", attribute_names, attribute_values);
1260       value = find_attribute ("value", attribute_names, attribute_values);
1261       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1262       
1263       if (name == NULL)
1264         MISSING_ATTRIBUTE (context, error, element_name, "name");
1265       else if (value == NULL)
1266         MISSING_ATTRIBUTE (context, error, element_name, "value");
1267       else 
1268         {             
1269           GIrNodeConstant *constant;
1270
1271           constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1272
1273           ((GIrNode *)constant)->name = g_strdup (name);
1274           constant->value = g_strdup (value);
1275
1276           ctx->current_typed = (GIrNode*) constant;
1277
1278           if (deprecated)
1279             constant->deprecated = TRUE;
1280           else
1281             constant->deprecated = FALSE;
1282
1283           if (ctx->state == STATE_NAMESPACE)
1284             {
1285               ctx->current_node = (GIrNode *) constant;
1286               ctx->current_module->entries = 
1287                 g_list_append (ctx->current_module->entries, constant);
1288             }
1289           else
1290             {
1291               GIrNodeInterface *iface;
1292
1293               iface = (GIrNodeInterface *)ctx->current_node;
1294               iface->members = g_list_append (iface->members, constant);
1295             }
1296
1297           switch (ctx->state)
1298             {
1299             case STATE_NAMESPACE:
1300               state_switch (ctx, STATE_NAMESPACE_CONSTANT);
1301               break;
1302             case STATE_CLASS:
1303               state_switch (ctx, STATE_CLASS_CONSTANT);
1304               break;
1305             case STATE_INTERFACE:
1306               state_switch (ctx, STATE_INTERFACE_CONSTANT);
1307               break;
1308             default:
1309               g_assert_not_reached ();
1310               break;
1311             }
1312         }
1313       
1314       return TRUE;
1315     }
1316   return FALSE;
1317 }
1318
1319 static gboolean
1320 start_errordomain (GMarkupParseContext *context,
1321                    const gchar         *element_name,
1322                    const gchar        **attribute_names,
1323                    const gchar        **attribute_values,
1324                    ParseContext        *ctx,
1325                    GError             **error)
1326 {
1327   if (strcmp (element_name, "errordomain") == 0 &&
1328       ctx->state == STATE_NAMESPACE)
1329     {
1330       const gchar *name;
1331       const gchar *getquark;
1332       const gchar *codes;
1333       const gchar *deprecated;
1334       
1335       name = find_attribute ("name", attribute_names, attribute_values);
1336       getquark = find_attribute ("get-quark", attribute_names, attribute_values);
1337       codes = find_attribute ("codes", attribute_names, attribute_values);
1338       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1339       
1340       if (name == NULL)
1341         MISSING_ATTRIBUTE (context, error, element_name, "name");
1342       else if (getquark == NULL)
1343         MISSING_ATTRIBUTE (context, error, element_name, "getquark");
1344       else if (codes == NULL)
1345         MISSING_ATTRIBUTE (context, error, element_name, "codes");
1346       else 
1347         {             
1348           GIrNodeErrorDomain *domain;
1349
1350           domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
1351
1352           ((GIrNode *)domain)->name = g_strdup (name);
1353           domain->getquark = g_strdup (getquark);
1354           domain->codes = g_strdup (codes);
1355
1356           if (deprecated)
1357             domain->deprecated = TRUE;
1358           else
1359             domain->deprecated = FALSE;
1360
1361           ctx->current_node = (GIrNode *) domain;
1362           ctx->current_module->entries = 
1363             g_list_append (ctx->current_module->entries, domain);
1364
1365           state_switch (ctx, STATE_ERRORDOMAIN);
1366         }
1367       
1368       return TRUE;
1369     }
1370   return FALSE;
1371 }
1372
1373 static gboolean
1374 start_interface (GMarkupParseContext *context,
1375                  const gchar         *element_name,
1376                  const gchar        **attribute_names,
1377                  const gchar        **attribute_values,
1378                  ParseContext        *ctx,
1379                  GError             **error)
1380 {
1381   if (strcmp (element_name, "interface") == 0 &&
1382       ctx->state == STATE_NAMESPACE)
1383     {
1384       const gchar *name;
1385       const gchar *typename;
1386       const gchar *typeinit;
1387       const gchar *deprecated;
1388       
1389       name = find_attribute ("name", attribute_names, attribute_values);
1390       typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1391       typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1392       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1393       
1394       if (name == NULL)
1395         MISSING_ATTRIBUTE (context, error, element_name, "name");
1396       else if (typename == NULL)
1397         MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1398       else if (typeinit == NULL)
1399         MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1400       else
1401         {
1402           GIrNodeInterface *iface;
1403
1404           iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE);
1405           ((GIrNode *)iface)->name = g_strdup (name);
1406           iface->gtype_name = g_strdup (typename);
1407           iface->gtype_init = g_strdup (typeinit);
1408           if (deprecated)
1409             iface->deprecated = TRUE;
1410           else
1411             iface->deprecated = FALSE;
1412           
1413           ctx->current_node = (GIrNode *) iface;
1414           ctx->current_module->entries = 
1415             g_list_append (ctx->current_module->entries, iface);              
1416           
1417           state_switch (ctx, STATE_INTERFACE);
1418           
1419         }
1420       
1421       return TRUE;
1422     }
1423   return FALSE;
1424 }
1425
1426 static gboolean
1427 start_class (GMarkupParseContext *context,
1428               const gchar         *element_name,
1429               const gchar        **attribute_names,
1430               const gchar        **attribute_values,
1431               ParseContext        *ctx,
1432               GError             **error)
1433 {
1434   if (strcmp (element_name, "class") == 0 &&
1435       ctx->state == STATE_NAMESPACE)
1436     {
1437       const gchar *name;
1438       const gchar *parent;
1439       const gchar *typename;
1440       const gchar *typeinit;
1441       const gchar *deprecated;
1442       const gchar *abstract;
1443       
1444       name = find_attribute ("name", attribute_names, attribute_values);
1445       parent = find_attribute ("parent", attribute_names, attribute_values);
1446       typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1447       typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1448       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1449       abstract = find_attribute ("abstract", attribute_names, attribute_values);
1450       
1451       if (name == NULL)
1452         MISSING_ATTRIBUTE (context, error, element_name, "name");
1453       else if (typename == NULL)
1454         MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1455       else if (typeinit == NULL && strcmp (typename, "GObject"))
1456         MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1457       else
1458         {
1459           GIrNodeInterface *iface;
1460
1461           iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT);
1462           ((GIrNode *)iface)->name = g_strdup (name);
1463           iface->gtype_name = g_strdup (typename);
1464           iface->gtype_init = g_strdup (typeinit);
1465           iface->parent = g_strdup (parent);
1466           if (deprecated)
1467             iface->deprecated = TRUE;
1468           else
1469             iface->deprecated = FALSE;
1470
1471           iface->abstract = abstract && strcmp (abstract, "1") == 0;
1472
1473           ctx->current_node = (GIrNode *) iface;
1474           ctx->current_module->entries = 
1475             g_list_append (ctx->current_module->entries, iface);              
1476           
1477           state_switch (ctx, STATE_CLASS);
1478         }
1479       
1480       return TRUE;
1481     }
1482   return  FALSE;
1483 }
1484
1485 static gboolean
1486 start_type (GMarkupParseContext *context,
1487             const gchar         *element_name,
1488             const gchar        **attribute_names,
1489             const gchar        **attribute_values,
1490             ParseContext       *ctx,
1491             GError             **error)
1492 {
1493   const gchar *name;
1494   const gchar *ctype;
1495   gboolean is_array;
1496   gboolean is_varargs;
1497   GIrNodeType *typenode;
1498
1499   is_array = strcmp (element_name, "array") == 0;
1500   is_varargs = strcmp (element_name, "varargs") == 0;
1501
1502   if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
1503     return FALSE;
1504
1505   if (ctx->state == STATE_TYPE) 
1506     {
1507       ctx->type_depth++;
1508       ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters);
1509       ctx->type_parameters = NULL;
1510     } 
1511   else if (ctx->state == STATE_FUNCTION_PARAMETER ||
1512            ctx->state == STATE_FUNCTION_RETURN || 
1513            ctx->state == STATE_STRUCT_FIELD ||
1514            ctx->state == STATE_UNION_FIELD ||
1515            ctx->state == STATE_CLASS_PROPERTY ||
1516            ctx->state == STATE_CLASS_FIELD ||
1517            ctx->state == STATE_INTERFACE_FIELD ||
1518            ctx->state == STATE_INTERFACE_PROPERTY ||
1519            ctx->state == STATE_BOXED_FIELD ||
1520            ctx->state == STATE_NAMESPACE_CONSTANT ||
1521            ctx->state == STATE_CLASS_CONSTANT ||
1522            ctx->state == STATE_INTERFACE_CONSTANT
1523            )
1524     {
1525       state_switch (ctx, STATE_TYPE);
1526       ctx->type_depth = 1;
1527       if (is_varargs)
1528         {
1529           switch (ctx->current_node->type)
1530             {
1531             case G_IR_NODE_FUNCTION:
1532             case G_IR_NODE_CALLBACK:
1533               {
1534                 GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
1535                 func->is_varargs = TRUE;
1536               }
1537               break;
1538             case G_IR_NODE_VFUNC:
1539               {
1540                 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
1541                 vfunc->is_varargs = TRUE;
1542               }
1543               break;
1544             /* list others individually rather than with default: so that compiler
1545              * warns if new node types are added without adding them to the switch
1546              */
1547             case G_IR_NODE_INVALID:
1548             case G_IR_NODE_ENUM:
1549             case G_IR_NODE_FLAGS:
1550             case G_IR_NODE_CONSTANT:
1551             case G_IR_NODE_ERROR_DOMAIN:
1552             case G_IR_NODE_PARAM:
1553             case G_IR_NODE_TYPE:
1554             case G_IR_NODE_PROPERTY:
1555             case G_IR_NODE_SIGNAL:
1556             case G_IR_NODE_VALUE:
1557             case G_IR_NODE_FIELD:
1558             case G_IR_NODE_XREF:
1559             case G_IR_NODE_STRUCT:
1560             case G_IR_NODE_BOXED:
1561             case G_IR_NODE_OBJECT:
1562             case G_IR_NODE_INTERFACE:
1563             case G_IR_NODE_UNION:
1564               g_assert_not_reached ();
1565               break;
1566             }
1567         }
1568       ctx->type_stack = NULL;
1569       ctx->type_parameters = NULL;
1570     }
1571
1572   if (!ctx->current_typed)
1573     {
1574       g_set_error (error,
1575                    G_MARKUP_ERROR,
1576                    G_MARKUP_ERROR_INVALID_CONTENT,
1577                    "The element <type> is invalid here");
1578       return FALSE;
1579     }
1580
1581   if (is_varargs)
1582     return TRUE;
1583
1584   if (is_array) 
1585     {
1586       const char *zero;
1587       const char *len;
1588       const char *size;
1589
1590       typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
1591
1592       typenode->tag = GI_TYPE_TAG_ARRAY;
1593       typenode->is_pointer = TRUE;
1594       typenode->is_array = TRUE;
1595       
1596       zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
1597       len = find_attribute ("length", attribute_names, attribute_values);
1598       size = find_attribute ("fixed-size", attribute_names, attribute_values);
1599       
1600       typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0);
1601       typenode->has_length = len != NULL;
1602       typenode->length = typenode->has_length ? atoi (len) : -1;
1603       
1604       typenode->has_size = size != NULL;
1605       typenode->size = typenode->has_size ? atoi (size) : -1;
1606     }
1607   else
1608     {
1609       gboolean is_pointer;
1610       name = find_attribute ("name", attribute_names, attribute_values);
1611
1612       if (name == NULL)
1613         MISSING_ATTRIBUTE (context, error, element_name, "name");
1614       
1615       ctype = find_attribute ("c:type", attribute_names, attribute_values);
1616       if (ctype != NULL && strchr (ctype, '*'))
1617         is_pointer = TRUE;
1618       else
1619         is_pointer = FALSE;
1620
1621       typenode = parse_type (ctx, name);
1622
1623       /* A 'disguised' structure is one where the c:type is a typedef that
1624        * doesn't look like a pointer, but is internally.
1625        */
1626       if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
1627           g_hash_table_lookup (ctx->disguised_structures, typenode->interface) != NULL)
1628         is_pointer = TRUE;
1629
1630       if (is_pointer)
1631         typenode->is_pointer = is_pointer;
1632     }
1633
1634   ctx->type_parameters = g_list_append (ctx->type_parameters, typenode);
1635   
1636   return TRUE;
1637 }
1638
1639 static void
1640 end_type_top (ParseContext *ctx)
1641 {
1642   GIrNodeType *typenode;
1643
1644   if (!ctx->type_parameters)
1645     goto out;
1646
1647   typenode = (GIrNodeType*)ctx->type_parameters->data;
1648
1649   /* Default to pointer for unspecified containers */
1650   if (typenode->tag == GI_TYPE_TAG_ARRAY ||
1651       typenode->tag == GI_TYPE_TAG_GLIST ||
1652       typenode->tag == GI_TYPE_TAG_GSLIST)
1653     {
1654       if (typenode->parameter_type1 == NULL)
1655         typenode->parameter_type1 = parse_type (ctx, "any");
1656     }
1657   else if (typenode->tag == GI_TYPE_TAG_GHASH)
1658     {
1659       if (typenode->parameter_type1 == NULL)
1660         {
1661           typenode->parameter_type1 = parse_type (ctx, "any");
1662           typenode->parameter_type2 = parse_type (ctx, "any");
1663         }
1664     }
1665
1666   switch (ctx->current_typed->type)
1667     {
1668     case G_IR_NODE_PARAM:
1669       {
1670         GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed;
1671         param->type = typenode;
1672       }
1673       break;
1674     case G_IR_NODE_FIELD:
1675       {
1676         GIrNodeField *field = (GIrNodeField *)ctx->current_typed;
1677         field->type = typenode;
1678       }
1679       break;
1680     case G_IR_NODE_PROPERTY:
1681       {
1682         GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed;
1683         property->type = typenode;
1684       }
1685       break;
1686     case G_IR_NODE_CONSTANT:
1687       {
1688         GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed;
1689         constant->type = typenode;
1690       }
1691       break;
1692     default:
1693       g_printerr("current node is %d\n", ctx->current_node->type);
1694       g_assert_not_reached ();
1695     }
1696   g_list_free (ctx->type_parameters);
1697
1698  out:  
1699   ctx->type_depth = 0;
1700   ctx->type_parameters = NULL;
1701   ctx->current_typed = NULL;
1702 }
1703
1704 static void
1705 end_type_recurse (ParseContext *ctx)
1706 {
1707   GIrNodeType *parent;
1708   GIrNodeType *param = NULL;
1709
1710   parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data;
1711   if (ctx->type_parameters)
1712     param = (GIrNodeType *) ctx->type_parameters->data;
1713
1714   if (parent->tag == GI_TYPE_TAG_ARRAY ||
1715       parent->tag == GI_TYPE_TAG_GLIST ||
1716       parent->tag == GI_TYPE_TAG_GSLIST)
1717     {
1718       g_assert (param != NULL);
1719
1720       if (parent->parameter_type1 == NULL)
1721         parent->parameter_type1 = param;
1722       else
1723         g_assert_not_reached ();
1724     }
1725   else if (parent->tag == GI_TYPE_TAG_GHASH)
1726     {
1727       g_assert (param != NULL);
1728
1729       if (parent->parameter_type1 == NULL)
1730         parent->parameter_type1 = param;
1731       else if (parent->parameter_type2 == NULL)
1732         parent->parameter_type2 = param;
1733       else
1734         g_assert_not_reached ();
1735     }
1736   g_list_free (ctx->type_parameters);
1737   ctx->type_parameters = (GList *)ctx->type_stack->data;
1738   ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
1739 }
1740
1741 static void
1742 end_type (ParseContext *ctx)
1743 {
1744   if (ctx->type_depth == 1)
1745     {
1746       end_type_top (ctx);
1747       state_switch (ctx, ctx->prev_state);
1748     }
1749   else
1750     {
1751       end_type_recurse (ctx);
1752       ctx->type_depth--;
1753     }
1754 }
1755
1756 static gboolean
1757 start_return_value (GMarkupParseContext *context,
1758                     const gchar         *element_name,
1759                     const gchar        **attribute_names,
1760                     const gchar        **attribute_values,
1761                     ParseContext       *ctx,
1762                     GError             **error)
1763 {
1764   if (strcmp (element_name, "return-value") == 0 &&
1765       ctx->state == STATE_FUNCTION)
1766     {
1767       GIrNodeParam *param;
1768       const gchar  *transfer;
1769
1770       param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
1771       param->in = FALSE;
1772       param->out = FALSE;
1773       param->retval = TRUE;
1774
1775       ctx->current_typed = (GIrNode*) param;
1776
1777       state_switch (ctx, STATE_FUNCTION_RETURN);
1778
1779       transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1780       parse_param_transfer (param, transfer);
1781
1782       switch (ctx->current_node->type)
1783         {
1784         case G_IR_NODE_FUNCTION:
1785         case G_IR_NODE_CALLBACK:
1786           {
1787             GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
1788             func->result = param;
1789           }
1790           break;
1791         case G_IR_NODE_SIGNAL:
1792           {
1793             GIrNodeSignal *signal = (GIrNodeSignal *)ctx->current_node;
1794             signal->result = param;
1795           }
1796           break;
1797         case G_IR_NODE_VFUNC:
1798           {
1799             GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
1800             vfunc->result = param;
1801           }
1802           break;
1803         default:
1804           g_assert_not_reached ();
1805         }
1806       
1807       return TRUE;
1808     }
1809
1810   return FALSE;
1811 }
1812
1813 static gboolean
1814 start_implements (GMarkupParseContext *context,
1815                   const gchar         *element_name,
1816                   const gchar        **attribute_names,
1817                   const gchar        **attribute_values,
1818                   ParseContext       *ctx,
1819                   GError             **error)
1820 {
1821   GIrNodeInterface *iface;
1822   const char *name;
1823
1824   if (strcmp (element_name, "implements") != 0 ||
1825       !(ctx->state == STATE_CLASS))
1826     return FALSE;
1827
1828   state_switch (ctx, STATE_IMPLEMENTS);
1829   
1830   name = find_attribute ("name", attribute_names, attribute_values);
1831   if (name == NULL)
1832     {
1833       MISSING_ATTRIBUTE (context, error, element_name, "name");
1834       return FALSE;
1835     }
1836       
1837   iface = (GIrNodeInterface *)ctx->current_node;
1838   iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
1839
1840   return TRUE;
1841 }
1842
1843 static gboolean
1844 start_glib_signal (GMarkupParseContext *context,
1845                    const gchar         *element_name,
1846                    const gchar        **attribute_names,
1847                    const gchar        **attribute_values,
1848                    ParseContext       *ctx,
1849                    GError             **error)
1850 {
1851   if (strcmp (element_name, "glib:signal") == 0 && 
1852       (ctx->state == STATE_CLASS ||
1853        ctx->state == STATE_INTERFACE))
1854     {
1855       const gchar *name;
1856       const gchar *when;
1857       const gchar *no_recurse;
1858       const gchar *detailed;
1859       const gchar *action;
1860       const gchar *no_hooks;
1861       const gchar *has_class_closure;
1862       
1863       name = find_attribute ("name", attribute_names, attribute_values);
1864       when = find_attribute ("when", attribute_names, attribute_values);
1865       no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values);
1866       detailed = find_attribute ("detailed", attribute_names, attribute_values);
1867       action = find_attribute ("action", attribute_names, attribute_values);
1868       no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values);
1869       has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values);
1870       
1871       if (name == NULL)
1872         MISSING_ATTRIBUTE (context, error, element_name, "name");
1873       else
1874         {
1875           GIrNodeInterface *iface;
1876           GIrNodeSignal *signal;
1877
1878           signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
1879           
1880           ((GIrNode *)signal)->name = g_strdup (name);
1881           
1882           signal->run_first = FALSE;
1883           signal->run_last = FALSE;
1884           signal->run_cleanup = FALSE;
1885           if (when == NULL || strcmp (when, "LAST") == 0)
1886             signal->run_last = TRUE;
1887           else if (strcmp (when, "FIRST") == 0)
1888             signal->run_first = TRUE;
1889           else 
1890             signal->run_cleanup = TRUE;
1891           
1892           if (no_recurse && strcmp (no_recurse, "1") == 0)
1893             signal->no_recurse = TRUE;
1894           else
1895             signal->no_recurse = FALSE;
1896           if (detailed && strcmp (detailed, "1") == 0)
1897             signal->detailed = TRUE;
1898           else
1899             signal->detailed = FALSE;
1900           if (action && strcmp (action, "1") == 0)
1901             signal->action = TRUE;
1902           else
1903             signal->action = FALSE;
1904           if (no_hooks && strcmp (no_hooks, "1") == 0)
1905             signal->no_hooks = TRUE;
1906           else
1907             signal->no_hooks = FALSE;
1908           if (has_class_closure && strcmp (has_class_closure, "1") == 0)
1909             signal->has_class_closure = TRUE;
1910           else
1911             signal->has_class_closure = FALSE;
1912
1913           iface = (GIrNodeInterface *)ctx->current_node;
1914           iface->members = g_list_append (iface->members, signal);
1915
1916           ctx->current_node = (GIrNode *)signal;
1917           state_switch (ctx, STATE_FUNCTION);
1918         }
1919       
1920       return TRUE;
1921     }
1922   return FALSE;
1923 }
1924
1925 static gboolean
1926 start_vfunc (GMarkupParseContext *context,
1927              const gchar         *element_name,
1928              const gchar        **attribute_names,
1929              const gchar        **attribute_values,
1930              ParseContext       *ctx,
1931              GError             **error)
1932 {
1933   if (strcmp (element_name, "vfunc") == 0 && 
1934       (ctx->state == STATE_CLASS ||
1935        ctx->state == STATE_INTERFACE))
1936     {
1937       const gchar *name;
1938       const gchar *must_chain_up;
1939       const gchar *override;
1940       const gchar *is_class_closure;
1941       const gchar *offset;
1942       
1943       name = find_attribute ("name", attribute_names, attribute_values);
1944       must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values);        
1945       override = find_attribute ("override", attribute_names, attribute_values);
1946       is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values);
1947       offset = find_attribute ("offset", attribute_names, attribute_values);
1948       
1949       if (name == NULL)
1950         MISSING_ATTRIBUTE (context, error, element_name, "name");
1951       else
1952         {
1953           GIrNodeInterface *iface;
1954           GIrNodeVFunc *vfunc;
1955
1956           vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
1957           
1958           ((GIrNode *)vfunc)->name = g_strdup (name);
1959
1960           if (must_chain_up && strcmp (must_chain_up, "1") == 0)
1961             vfunc->must_chain_up = TRUE;
1962           else
1963             vfunc->must_chain_up = FALSE;
1964
1965           if (override && strcmp (override, "always") == 0)
1966             {
1967               vfunc->must_be_implemented = TRUE;
1968               vfunc->must_not_be_implemented = FALSE;
1969             }
1970           else if (override && strcmp (override, "never") == 0)
1971             {
1972               vfunc->must_be_implemented = FALSE;
1973               vfunc->must_not_be_implemented = TRUE;
1974             }
1975           else
1976             {
1977               vfunc->must_be_implemented = FALSE;
1978               vfunc->must_not_be_implemented = FALSE;
1979             }
1980           
1981           if (is_class_closure && strcmp (is_class_closure, "1") == 0)
1982             vfunc->is_class_closure = TRUE;
1983           else
1984             vfunc->is_class_closure = FALSE;
1985           
1986           if (offset)
1987             vfunc->offset = atoi (offset);
1988           else
1989             vfunc->offset = 0;
1990
1991           iface = (GIrNodeInterface *)ctx->current_node;
1992           iface->members = g_list_append (iface->members, vfunc);
1993
1994           ctx->current_node = (GIrNode *)vfunc;
1995           state_switch (ctx, STATE_FUNCTION);
1996         }
1997       
1998       return TRUE;
1999     }
2000   return FALSE;
2001 }
2002
2003
2004 static gboolean
2005 start_struct (GMarkupParseContext *context,
2006               const gchar         *element_name,
2007               const gchar        **attribute_names,
2008               const gchar        **attribute_values,
2009               ParseContext       *ctx,
2010               GError             **error)
2011 {
2012   if (strcmp (element_name, "record") == 0 && 
2013       ctx->state == STATE_NAMESPACE)
2014     {
2015       const gchar *name;
2016       const gchar *deprecated;
2017       const gchar *disguised;
2018       const gchar *gtype_name;
2019       const gchar *gtype_init;
2020       GIrNodeStruct *struct_;
2021       
2022       name = find_attribute ("name", attribute_names, attribute_values);
2023       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2024       disguised = find_attribute ("disguised", attribute_names, attribute_values);
2025       gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
2026       gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
2027
2028       if (name == NULL)
2029         {
2030           MISSING_ATTRIBUTE (context, error, element_name, "name");
2031           return FALSE;
2032         }
2033       if ((gtype_name == NULL && gtype_init != NULL))
2034         {
2035           MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
2036           return FALSE;
2037         }
2038       if ((gtype_name != NULL && gtype_init == NULL))
2039         {
2040           MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
2041           return FALSE;
2042         }
2043
2044       struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
2045       
2046       ((GIrNode *)struct_)->name = g_strdup (name);
2047       if (deprecated)
2048         struct_->deprecated = TRUE;
2049       else
2050         struct_->deprecated = FALSE;
2051
2052       if (disguised && strcmp (disguised, "1") == 0)
2053         struct_->disguised = TRUE;
2054
2055       struct_->gtype_name = g_strdup (gtype_name);
2056       struct_->gtype_init = g_strdup (gtype_init);
2057       
2058       ctx->current_node = (GIrNode *)struct_;
2059       ctx->current_module->entries = 
2060         g_list_append (ctx->current_module->entries, struct_);
2061       
2062       state_switch (ctx, STATE_STRUCT);
2063       return TRUE;
2064     }
2065   return FALSE;
2066 }
2067   
2068
2069 static gboolean
2070 start_union (GMarkupParseContext *context,
2071              const gchar         *element_name,
2072              const gchar        **attribute_names,
2073              const gchar        **attribute_values,
2074              ParseContext       *ctx,
2075              GError             **error)
2076 {
2077   if (strcmp (element_name, "union") == 0 && 
2078       ctx->state == STATE_NAMESPACE)
2079     {
2080       const gchar *name;
2081       const gchar *deprecated;
2082       const gchar *typename;
2083       const gchar *typeinit;
2084       
2085       name = find_attribute ("name", attribute_names, attribute_values);
2086       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2087       typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
2088       typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
2089       
2090       if (name == NULL)
2091         MISSING_ATTRIBUTE (context, error, element_name, "name");
2092       else
2093         {
2094           GIrNodeUnion *union_;
2095
2096           union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
2097           
2098           ((GIrNode *)union_)->name = g_strdup (name);
2099           union_->gtype_name = g_strdup (typename);
2100           union_->gtype_init = g_strdup (typeinit);
2101           if (deprecated)
2102             union_->deprecated = TRUE;
2103           else
2104             union_->deprecated = FALSE;
2105
2106           ctx->current_node = (GIrNode *)union_;
2107           ctx->current_module->entries = 
2108             g_list_append (ctx->current_module->entries, union_);
2109           
2110           state_switch (ctx, STATE_UNION);
2111         }
2112       return TRUE;
2113     }
2114   return FALSE;
2115 }
2116
2117 static gboolean
2118 start_discriminator (GMarkupParseContext *context,
2119                      const gchar         *element_name,
2120                      const gchar        **attribute_names,
2121                      const gchar        **attribute_values,
2122                      ParseContext       *ctx,
2123                      GError             **error)
2124 {
2125   if (strcmp (element_name, "discriminator") == 0 &&
2126       ctx->state == STATE_UNION)
2127     {
2128       const gchar *type;
2129       const gchar *offset;
2130       
2131       type = find_attribute ("type", attribute_names, attribute_values);
2132       offset = find_attribute ("offset", attribute_names, attribute_values);
2133       if (type == NULL)
2134         MISSING_ATTRIBUTE (context, error, element_name, "type");
2135       else if (offset == NULL)
2136         MISSING_ATTRIBUTE (context, error, element_name, "offset");
2137         {
2138           ((GIrNodeUnion *)ctx->current_node)->discriminator_type 
2139             = parse_type (ctx, type);
2140           ((GIrNodeUnion *)ctx->current_node)->discriminator_offset 
2141             = atoi (offset);
2142         }
2143       
2144       return TRUE;
2145     }
2146
2147   return FALSE;
2148 }
2149
2150 static gboolean
2151 parse_include (GMarkupParseContext *context,
2152                ParseContext        *ctx,
2153                const char          *name,
2154                const char          *version,
2155                GError             **error)
2156 {
2157   ParseContext sub_ctx = { 0 };
2158   gchar *buffer;
2159   gsize length;
2160   char *girpath;
2161   gboolean success = FALSE;
2162   GList *l;
2163
2164   for (l = ctx->include_modules; l; l = l->next)
2165     {
2166       GIrModule *m = l->data;
2167
2168       if (strcmp (m->name, name) == 0)
2169         {
2170           if (strcmp (m->version, version) == 0)
2171             {
2172               return TRUE;
2173             }
2174           else
2175             {
2176               g_set_error (error,
2177                            G_MARKUP_ERROR,
2178                            G_MARKUP_ERROR_INVALID_CONTENT,
2179                            "Module '%s' imported with conflicting versions '%s' and '%s'",
2180                            name, m->version, version);
2181               return FALSE;
2182             }
2183         }
2184     }
2185
2186   girpath = locate_gir (name, version, ctx->includes);
2187
2188   if (girpath == NULL)
2189     {
2190       g_set_error (error,
2191                    G_MARKUP_ERROR,
2192                    G_MARKUP_ERROR_INVALID_CONTENT,
2193                    "Could not find GIR file '%s.gir'; check XDG_DATA_DIRS or use --includedir",
2194                    name);
2195       return FALSE;
2196     }
2197
2198   g_debug ("Parsing include %s", girpath);
2199
2200   if (!g_file_get_contents (girpath, &buffer, &length, error))
2201     {
2202       g_free (girpath);
2203       return FALSE;
2204     }
2205   g_free (girpath);
2206
2207   sub_ctx.state = STATE_START;
2208   sub_ctx.includes = ctx->includes;
2209   sub_ctx.prefix_aliases = TRUE;
2210   sub_ctx.namespace = name;
2211   sub_ctx.aliases = ctx->aliases;
2212   sub_ctx.disguised_structures = ctx->disguised_structures;
2213   sub_ctx.type_depth = 0;
2214
2215   context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL);
2216
2217   if (!g_markup_parse_context_parse (context, buffer, length, error))
2218     goto out;
2219
2220   if (!g_markup_parse_context_end_parse (context, error))
2221     goto out;
2222
2223   g_markup_parse_context_free (context);
2224
2225   context = g_markup_parse_context_new (&parser, 0, &sub_ctx, NULL);
2226   if (!g_markup_parse_context_parse (context, buffer, length, error))
2227     goto out;
2228
2229   if (!g_markup_parse_context_end_parse (context, error))
2230     goto out;
2231
2232   success = TRUE;
2233
2234  out:
2235   ctx->include_modules = g_list_concat (ctx->include_modules,
2236                                         sub_ctx.modules);
2237
2238   g_markup_parse_context_free (context);
2239   g_free (buffer);
2240
2241   return success;
2242 }
2243   
2244 extern GLogLevelFlags logged_levels;
2245
2246 static void
2247 start_element_handler (GMarkupParseContext *context,
2248                        const gchar         *element_name,
2249                        const gchar        **attribute_names,
2250                        const gchar        **attribute_values,
2251                        gpointer             user_data,
2252                        GError             **error)
2253 {
2254   ParseContext *ctx = user_data;
2255   gint line_number, char_number;
2256
2257   if (logged_levels & G_LOG_LEVEL_DEBUG)
2258     {
2259       GString *tags = g_string_new ("");
2260       int i;
2261       for (i = 0; attribute_names[i]; i++)
2262         g_string_append_printf (tags, "%s=\"%s\" ",
2263                                 attribute_names[i],
2264                                 attribute_values[i]);
2265
2266       if (i)
2267         {
2268           g_string_insert_c (tags, 0, ' ');
2269           g_string_truncate (tags, tags->len - 1);
2270         }
2271       g_debug ("<%s%s>", element_name, tags->str);
2272       g_string_free (tags, TRUE);
2273     }
2274
2275   switch (element_name[0]) 
2276     {
2277     case 'a':
2278       if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0) 
2279         {
2280           state_switch (ctx, STATE_ALIAS);
2281           goto out;
2282         }
2283       if (start_type (context, element_name,
2284                       attribute_names, attribute_values,
2285                       ctx, error))
2286         goto out;
2287       break;
2288     case 'b':
2289       if (start_enum (context, element_name, 
2290                       attribute_names, attribute_values,
2291                       ctx, error))
2292         goto out;
2293       break;
2294     case 'c':
2295       if (start_function (context, element_name, 
2296                           attribute_names, attribute_values,
2297                           ctx, error))
2298         goto out;
2299       else if (start_constant (context, element_name,
2300                                attribute_names, attribute_values,
2301                                ctx, error))
2302         goto out;
2303       else if (start_class (context, element_name, 
2304                             attribute_names, attribute_values,
2305                             ctx, error))
2306         goto out;
2307       else if (strcmp (element_name, "class") == 0 &&
2308                ctx->state == STATE_REQUIRES)
2309         {
2310           const gchar *name;
2311
2312           name = find_attribute ("name", attribute_names, attribute_values);
2313
2314           if (name == NULL)
2315             MISSING_ATTRIBUTE (context, error, element_name, "name");
2316           else
2317             {  
2318               GIrNodeInterface *iface;
2319
2320               iface = (GIrNodeInterface *)ctx->current_node;
2321               iface ->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
2322             }
2323
2324           goto out;
2325         }
2326       break;
2327
2328     case 'd':
2329       if (start_discriminator (context, element_name, 
2330                                attribute_names, attribute_values,
2331                                ctx, error))
2332         goto out;
2333       break;
2334
2335     case 'e':
2336       if (start_enum (context, element_name, 
2337                       attribute_names, attribute_values,
2338                       ctx, error))
2339         goto out;
2340       else if (start_errordomain (context, element_name, 
2341                       attribute_names, attribute_values,
2342                       ctx, error))
2343         goto out;
2344       break;
2345
2346     case 'f':
2347       if (start_function (context, element_name, 
2348                           attribute_names, attribute_values,
2349                           ctx, error))
2350         goto out;
2351       else if (start_field (context, element_name, 
2352                             attribute_names, attribute_values,
2353                             ctx, error))
2354         goto out;
2355       break;
2356
2357     case 'g':
2358       if (start_glib_boxed (context, element_name,
2359                             attribute_names, attribute_values,
2360                             ctx, error))
2361         goto out;
2362       else if (start_glib_signal (context, element_name,
2363                              attribute_names, attribute_values,
2364                              ctx, error))
2365         goto out;
2366       break;
2367
2368     case 'i':
2369       if (strcmp (element_name, "include") == 0 &&
2370           ctx->state == STATE_REPOSITORY)
2371         {
2372           const gchar *name;
2373           const gchar *version;
2374
2375           name = find_attribute ("name", attribute_names, attribute_values);
2376           version = find_attribute ("version", attribute_names, attribute_values);
2377
2378           if (name == NULL)
2379             {
2380               MISSING_ATTRIBUTE (context, error, element_name, "name");
2381               break;
2382             }
2383           if (version == NULL)
2384             {
2385               MISSING_ATTRIBUTE (context, error, element_name, "version");
2386               break;
2387             }
2388
2389           if (!parse_include (context, ctx, name, version, error))
2390             break;
2391
2392           ctx->dependencies = g_list_prepend (ctx->dependencies,
2393                                               g_strdup_printf ("%s-%s", name, version));
2394
2395
2396           state_switch (ctx, STATE_INCLUDE);
2397           goto out;
2398         }
2399       if (start_interface (context, element_name, 
2400                            attribute_names, attribute_values,
2401                            ctx, error))
2402         goto out;
2403       else if (start_implements (context, element_name,
2404                                  attribute_names, attribute_values,
2405                                  ctx, error))
2406         goto out;
2407       break;
2408
2409     case 'm':
2410       if (start_function (context, element_name, 
2411                           attribute_names, attribute_values,
2412                           ctx, error))
2413         goto out;
2414       else if (start_member (context, element_name, 
2415                           attribute_names, attribute_values,
2416                           ctx, error))
2417         goto out;
2418       break;
2419
2420     case 'n':
2421       if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2422         {
2423           const gchar *name, *version, *shared_library;
2424           
2425           name = find_attribute ("name", attribute_names, attribute_values);
2426           version = find_attribute ("version", attribute_names, attribute_values);
2427           shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2428
2429           if (name == NULL)
2430             MISSING_ATTRIBUTE (context, error, element_name, "name");
2431           else if (version == NULL)
2432             MISSING_ATTRIBUTE (context, error, element_name, "version");
2433           else
2434             {
2435               ctx->current_module = g_ir_module_new (name, version, shared_library);
2436               ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2437               ctx->current_module->dependencies = ctx->dependencies;
2438               ctx->current_module->include_modules = g_list_copy (ctx->include_modules);
2439
2440               state_switch (ctx, STATE_NAMESPACE);
2441               goto out;
2442             }
2443         }
2444       break;
2445
2446     case 'p':
2447       if (start_property (context, element_name,
2448                           attribute_names, attribute_values,
2449                           ctx, error))
2450         goto out;
2451       else if (strcmp (element_name, "parameters") == 0 &&
2452                ctx->state == STATE_FUNCTION)
2453         {
2454           state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2455
2456           goto out;
2457         }
2458       else if (start_parameter (context, element_name,
2459                                 attribute_names, attribute_values,
2460                                 ctx, error))
2461         goto out;
2462
2463       break;
2464
2465     case 'r':
2466       if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
2467         {
2468           const gchar *version;
2469
2470           version = find_attribute ("version", attribute_names, attribute_values);
2471           
2472           if (version == NULL)
2473             MISSING_ATTRIBUTE (context, error, element_name, "version");
2474           else if (strcmp (version, "1.0") != 0)
2475             g_set_error (error,
2476                          G_MARKUP_ERROR,
2477                          G_MARKUP_ERROR_INVALID_CONTENT,
2478                          "Unsupported version '%s'",
2479                          version);
2480           else
2481             state_switch (ctx, STATE_REPOSITORY);
2482           
2483           goto out;
2484         }
2485       else if (start_return_value (context, element_name,
2486                                    attribute_names, attribute_values,
2487                                    ctx, error))
2488         goto out;      
2489       else if (strcmp (element_name, "requires") == 0 &&
2490                ctx->state == STATE_INTERFACE)
2491         {
2492           state_switch (ctx, STATE_REQUIRES);
2493           
2494           goto out;
2495         }
2496       else if (start_struct (context, element_name,
2497                              attribute_names, attribute_values,
2498                              ctx, error))
2499         goto out;      
2500       break;
2501
2502     case 'u':
2503       if (start_union (context, element_name,
2504                        attribute_names, attribute_values,
2505                        ctx, error))
2506         goto out;
2507       break;
2508
2509     case 't':
2510       if (start_type (context, element_name,
2511                       attribute_names, attribute_values,
2512                       ctx, error))
2513         goto out;
2514       break;
2515
2516     case 'v':
2517       if (start_vfunc (context, element_name,
2518                        attribute_names, attribute_values,
2519                        ctx, error))
2520         goto out;
2521       if (start_type (context, element_name,
2522                       attribute_names, attribute_values,
2523                       ctx, error))
2524         goto out;
2525       break;
2526     }
2527
2528   g_markup_parse_context_get_position (context, &line_number, &char_number);
2529
2530   if (error && *error == NULL)
2531     g_set_error (error,
2532                  G_MARKUP_ERROR,
2533                  G_MARKUP_ERROR_UNKNOWN_ELEMENT,
2534                  "Unexpected start tag '%s' on line %d char %d; current state=%d",
2535                  element_name,
2536                  line_number, char_number, ctx->state);
2537   
2538  out: ;
2539   if (*error) 
2540     {
2541       g_markup_parse_context_get_position (context, &line_number, &char_number);
2542
2543       fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message);
2544       backtrace_stderr ();
2545     }
2546 }
2547
2548 static gboolean
2549 require_one_of_end_elements (GMarkupParseContext *context,
2550                              ParseContext        *ctx,
2551                              const char          *actual_name,
2552                              GError             **error, 
2553                              ...)
2554 {
2555   va_list args;
2556   int line_number, char_number;
2557   const char *expected;
2558   gboolean matched = FALSE;
2559
2560   va_start (args, error);
2561
2562   while ((expected = va_arg (args, const char*)) != NULL) 
2563     {
2564       if (strcmp (expected, actual_name) == 0)
2565         {
2566           matched = TRUE;
2567           break;
2568         }
2569     }
2570
2571   va_end (args);
2572
2573   if (matched)
2574     return TRUE;
2575
2576   g_markup_parse_context_get_position (context, &line_number, &char_number);
2577   g_set_error (error,
2578                G_MARKUP_ERROR,
2579                G_MARKUP_ERROR_INVALID_CONTENT,
2580                "Unexpected end tag '%s' on line %d char %d; current state=%d",
2581                actual_name, 
2582                line_number, char_number, ctx->state);
2583   backtrace_stderr();
2584   return FALSE;
2585 }
2586
2587 static gboolean
2588 require_end_element (GMarkupParseContext *context,
2589                      ParseContext        *ctx,
2590                      const char          *expected_name,
2591                      const char          *actual_name,
2592                      GError             **error)
2593 {
2594   return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
2595 }
2596
2597 static void
2598 end_element_handler (GMarkupParseContext *context,
2599                      const gchar         *element_name,
2600                      gpointer             user_data,
2601                      GError             **error)
2602 {
2603   ParseContext *ctx = user_data;
2604
2605   g_debug ("</%s>", element_name);
2606
2607   switch (ctx->state)
2608     {
2609     case STATE_START:
2610     case STATE_END:
2611       /* no need to GError here, GMarkup already catches this */
2612       break;
2613
2614     case STATE_REPOSITORY:
2615       state_switch (ctx, STATE_END);
2616       break;
2617
2618     case STATE_INCLUDE:
2619       if (require_end_element (context, ctx, "include", element_name, error))
2620         {
2621           state_switch (ctx, STATE_REPOSITORY);
2622         }
2623       break;
2624
2625     case STATE_NAMESPACE:
2626       if (require_end_element (context, ctx, "namespace", element_name, error))
2627         {
2628           ctx->current_module = NULL;
2629           state_switch (ctx, STATE_REPOSITORY);
2630         }
2631       break;
2632
2633     case STATE_ALIAS:
2634       if (require_end_element (context, ctx, "alias", element_name, error))
2635         {
2636           state_switch (ctx, STATE_NAMESPACE);
2637         }
2638       break;
2639
2640     case STATE_FUNCTION_RETURN:
2641       if (strcmp ("type", element_name) == 0)
2642         break;
2643       if (require_end_element (context, ctx, "return-value", element_name, error))
2644         {
2645           state_switch (ctx, STATE_FUNCTION);
2646         }
2647       break;
2648
2649     case STATE_FUNCTION_PARAMETERS:
2650       if (require_end_element (context, ctx, "parameters", element_name, error))
2651         {
2652           state_switch (ctx, STATE_FUNCTION);
2653         }
2654       break;
2655
2656     case STATE_FUNCTION_PARAMETER:
2657       if (strcmp ("type", element_name) == 0)
2658         break;
2659       if (require_end_element (context, ctx, "parameter", element_name, error))
2660         {
2661           state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2662         }
2663       break;
2664
2665     case STATE_FUNCTION:
2666       {
2667         gboolean current_is_toplevel;
2668         GList *last = g_list_last (ctx->current_module->entries);
2669         
2670         current_is_toplevel = ctx->current_node == last->data;  
2671
2672         if (current_is_toplevel)
2673           {
2674             ctx->current_node = NULL;
2675             state_switch (ctx, STATE_NAMESPACE);
2676           }
2677         else 
2678           { 
2679             ctx->current_node = g_list_last (ctx->current_module->entries)->data;
2680             if (ctx->current_node->type == G_IR_NODE_INTERFACE)
2681               state_switch (ctx, STATE_INTERFACE);
2682             else if (ctx->current_node->type == G_IR_NODE_OBJECT) 
2683               state_switch (ctx, STATE_CLASS);
2684             else if (ctx->current_node->type == G_IR_NODE_BOXED)
2685               state_switch (ctx, STATE_BOXED);
2686             else if (ctx->current_node->type == G_IR_NODE_STRUCT)
2687               state_switch (ctx, STATE_STRUCT);
2688             else if (ctx->current_node->type == G_IR_NODE_UNION)
2689               state_switch (ctx, STATE_UNION);
2690             else
2691               {
2692                 int line_number, char_number;
2693                 g_markup_parse_context_get_position (context, &line_number, &char_number);
2694                 g_set_error (error,
2695                              G_MARKUP_ERROR,
2696                              G_MARKUP_ERROR_INVALID_CONTENT,
2697                              "Unexpected end tag '%s' on line %d char %d",
2698                              element_name,
2699                              line_number, char_number);
2700               }
2701           }
2702       }
2703       break;
2704
2705     case STATE_CLASS_FIELD:
2706       if (strcmp ("type", element_name) == 0)
2707         break;
2708       if (require_end_element (context, ctx, "field", element_name, error))
2709         {
2710           state_switch (ctx, STATE_CLASS);
2711         }
2712       break;
2713
2714     case STATE_CLASS_PROPERTY:
2715       if (strcmp ("type", element_name) == 0)
2716         break;
2717       if (require_end_element (context, ctx, "property", element_name, error))
2718         {
2719           state_switch (ctx, STATE_CLASS);
2720         }
2721       break;
2722
2723     case STATE_CLASS:
2724       if (require_end_element (context, ctx, "class", element_name, error))
2725         {
2726           ctx->current_node = NULL;
2727           state_switch (ctx, STATE_NAMESPACE);
2728         }
2729       break;
2730
2731     case STATE_ERRORDOMAIN:
2732       if (require_end_element (context, ctx, "errordomain", element_name, error))
2733         {
2734           ctx->current_node = NULL;
2735           state_switch (ctx, STATE_NAMESPACE);
2736         }
2737       break;
2738
2739     case STATE_INTERFACE_PROPERTY:
2740       if (strcmp ("type", element_name) == 0)
2741         break;
2742       if (require_end_element (context, ctx, "property", element_name, error))
2743         {
2744           state_switch (ctx, STATE_INTERFACE);
2745         }
2746       break;
2747
2748     case STATE_INTERFACE_FIELD:
2749       if (strcmp ("type", element_name) == 0)
2750         break;
2751       if (require_end_element (context, ctx, "field", element_name, error))
2752         {
2753           state_switch (ctx, STATE_INTERFACE);
2754         }
2755       break;
2756
2757     case STATE_INTERFACE:
2758       if (require_end_element (context, ctx, "interface", element_name, error))
2759         {
2760           ctx->current_node = NULL;
2761           state_switch (ctx, STATE_NAMESPACE);
2762         }
2763       break;
2764
2765     case STATE_ENUM:
2766       if (strcmp ("member", element_name) == 0)
2767         break;
2768       else if (require_one_of_end_elements (context, ctx, 
2769                                             element_name, error, "enumeration", 
2770                                             "bitfield", NULL))
2771         {
2772           ctx->current_node = NULL;
2773           state_switch (ctx, STATE_NAMESPACE);
2774         }
2775       break;
2776
2777     case STATE_BOXED:
2778       if (require_end_element (context, ctx, "glib:boxed", element_name, error))
2779         {
2780           ctx->current_node = NULL;
2781           state_switch (ctx, STATE_NAMESPACE);
2782         }
2783       break;
2784
2785     case STATE_BOXED_FIELD:
2786       if (strcmp ("type", element_name) == 0)
2787         break;
2788       if (require_end_element (context, ctx, "field", element_name, error))
2789         {
2790           state_switch (ctx, STATE_BOXED);
2791         }
2792       break;
2793
2794     case STATE_STRUCT_FIELD:
2795       if (strcmp ("type", element_name) == 0)
2796         break;
2797       if (require_end_element (context, ctx, "field", element_name, error))
2798         {
2799           state_switch (ctx, STATE_STRUCT);
2800         }
2801       break;
2802
2803     case STATE_STRUCT:
2804       if (require_end_element (context, ctx, "record", element_name, error))
2805         {
2806           ctx->current_node = NULL;
2807           state_switch (ctx, STATE_NAMESPACE);
2808         }
2809       break;
2810
2811     case STATE_UNION_FIELD:
2812       if (strcmp ("type", element_name) == 0)
2813         break;
2814       if (require_end_element (context, ctx, "field", element_name, error))
2815         {
2816           state_switch (ctx, STATE_UNION);
2817         }
2818       break;
2819
2820     case STATE_UNION:
2821       if (require_end_element (context, ctx, "union", element_name, error))
2822         {
2823           ctx->current_node = NULL;
2824           state_switch (ctx, STATE_NAMESPACE);
2825         }
2826       break;
2827     case STATE_IMPLEMENTS:
2828       if (strcmp ("interface", element_name) == 0)
2829         break;
2830       if (require_end_element (context, ctx, "implements", element_name, error))
2831         state_switch (ctx, STATE_CLASS);
2832       break;
2833     case STATE_REQUIRES:
2834       if (require_end_element (context, ctx, "requires", element_name, error))
2835         state_switch (ctx, STATE_INTERFACE);
2836       break;
2837     case STATE_NAMESPACE_CONSTANT:
2838     case STATE_CLASS_CONSTANT:
2839     case STATE_INTERFACE_CONSTANT:
2840       if (strcmp ("type", element_name) == 0)
2841         break;
2842       if (require_end_element (context, ctx, "constant", element_name, error))
2843         {
2844           ctx->current_node = NULL;
2845           switch (ctx->state)
2846             {
2847             case STATE_NAMESPACE_CONSTANT:
2848               state_switch (ctx, STATE_NAMESPACE);
2849               break;
2850             case STATE_CLASS_CONSTANT:
2851               state_switch (ctx, STATE_CLASS);
2852               break;
2853             case STATE_INTERFACE_CONSTANT:
2854               state_switch (ctx, STATE_INTERFACE);
2855               break;
2856             default:
2857               g_assert_not_reached ();
2858               break;
2859             }
2860         }
2861       break;
2862     case STATE_TYPE:
2863       if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
2864           (strcmp ("varargs", element_name) == 0))
2865         {
2866           end_type (ctx);
2867           break;
2868         }
2869     default:
2870       g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
2871     }
2872 }
2873
2874 static void 
2875 text_handler (GMarkupParseContext *context,
2876               const gchar         *text,
2877               gsize                text_len,  
2878               gpointer             user_data,
2879               GError             **error)
2880 {
2881   /* FIXME warn about non-whitespace text */
2882 }
2883
2884 static void
2885 cleanup (GMarkupParseContext *context,
2886          GError              *error,
2887          gpointer             user_data)
2888 {
2889   ParseContext *ctx = user_data;
2890   GList *m;
2891
2892   for (m = ctx->modules; m; m = m->next)
2893     g_ir_module_free (m->data);
2894   g_list_free (ctx->modules);
2895   ctx->modules = NULL;
2896   
2897   ctx->current_module = NULL;
2898 }
2899
2900 static GList *
2901 post_filter_varargs_functions (GList *list)
2902 {
2903   GList *iter;
2904
2905   iter = list;
2906   while (iter)
2907     {
2908       GList *link = iter;
2909       GIrNode *node = iter->data;
2910
2911       iter = iter->next;
2912
2913       if (node->type == G_IR_NODE_FUNCTION)
2914         {
2915           if (((GIrNodeFunction*)node)->is_varargs)
2916             {
2917               list = g_list_delete_link (list, link);
2918             }
2919         }
2920     }
2921   return list;
2922 }
2923
2924 static void
2925 post_filter (GIrModule *module)
2926 {
2927   GList *iter;
2928
2929   module->entries = post_filter_varargs_functions (module->entries);
2930   iter = module->entries;
2931   while (iter)
2932     {
2933       GIrNode *node = iter->data;
2934
2935       iter = iter->next;
2936       
2937       if (node->type == G_IR_NODE_OBJECT || 
2938           node->type == G_IR_NODE_INTERFACE) 
2939         {
2940           GIrNodeInterface *iface = (GIrNodeInterface*)node;
2941           iface->members = post_filter_varargs_functions (iface->members);
2942         }
2943       else if (node->type == G_IR_NODE_BOXED)
2944         {
2945           GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
2946           boxed->members = post_filter_varargs_functions (boxed->members);
2947         }
2948       else if (node->type == G_IR_NODE_STRUCT)
2949         {
2950           GIrNodeStruct *iface = (GIrNodeStruct*)node;
2951           iface->members = post_filter_varargs_functions (iface->members);
2952         }
2953       else if (node->type == G_IR_NODE_UNION)
2954         {
2955           GIrNodeUnion *iface = (GIrNodeUnion*)node;
2956           iface->members = post_filter_varargs_functions (iface->members);
2957         }
2958     }
2959 }
2960
2961 GList * 
2962 g_ir_parse_string (const gchar  *namespace,
2963                    const gchar *const *includes,
2964                    const gchar  *buffer, 
2965                    gssize        length,
2966                    GError      **error)
2967 {
2968   ParseContext ctx = { 0 };
2969   GMarkupParseContext *context;
2970
2971   ctx.state = STATE_START;
2972   ctx.includes = includes;
2973   ctx.prefix_aliases = FALSE;
2974   ctx.namespace = namespace;
2975   ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
2976   ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
2977   ctx.type_depth = 0;
2978   ctx.dependencies = NULL;
2979   ctx.current_module = NULL;
2980
2981   context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
2982
2983   if (!g_markup_parse_context_parse (context, buffer, length, error))
2984     goto out;
2985
2986   if (!g_markup_parse_context_end_parse (context, error))
2987     goto out;
2988
2989   g_markup_parse_context_free (context);
2990   
2991   context = g_markup_parse_context_new (&parser, 0, &ctx, NULL);
2992   if (!g_markup_parse_context_parse (context, buffer, length, error))
2993     goto out;
2994
2995   if (!g_markup_parse_context_end_parse (context, error))
2996     goto out;
2997
2998  out:
2999
3000   g_hash_table_destroy (ctx.aliases);
3001   g_hash_table_destroy (ctx.disguised_structures);
3002   
3003   g_markup_parse_context_free (context);
3004   
3005   return ctx.modules;
3006 }
3007
3008 GList *
3009 g_ir_parse_file (const gchar  *filename,
3010                  const gchar *const *includes,
3011                  GError      **error)
3012 {
3013   gchar *buffer;
3014   gsize length;
3015   GList *modules;
3016   GList *iter;
3017   const char *slash;
3018   char *namespace;
3019
3020   if (!g_str_has_suffix (filename, ".gir"))
3021     {
3022       g_set_error (error,
3023                    G_MARKUP_ERROR,
3024                    G_MARKUP_ERROR_INVALID_CONTENT,
3025                    "Expected filename to end with '.gir'");
3026       return NULL;
3027     }
3028
3029   g_debug ("[parsing] filename %s", filename);
3030
3031   slash = g_strrstr (filename, "/");
3032   if (!slash)
3033     namespace = g_strdup (filename);
3034   else
3035     namespace = g_strdup (slash+1);
3036   namespace[strlen(namespace)-4] = '\0';
3037
3038   if (!g_file_get_contents (filename, &buffer, &length, error))
3039     return NULL;
3040   
3041   modules = g_ir_parse_string (namespace, includes, buffer, length, error);
3042
3043   for (iter = modules; iter; iter = iter->next) 
3044     {
3045       post_filter ((GIrModule*)iter->data);
3046     }
3047
3048   g_free (namespace);
3049
3050   g_free (buffer);
3051
3052   return modules;
3053 }
3054
3055