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