Bug 560250 - Fully parse included modules
[gnome.gobject-introspection] / girepository / girparser.c
1 /* GObject introspection: A parser for the XML GIR format
2  *
3  * Copyright (C) 2008 Philip Van Hoof
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdio.h>
24
25 #include <glib.h>
26 #include "girparser.h"
27 #include "girmodule.h"
28 #include "girnode.h"
29 #include "gtypelib.h"
30
31 typedef enum
32 {
33   STATE_START,    
34   STATE_END,        
35   STATE_REPOSITORY, 
36   STATE_INCLUDE,  
37   STATE_NAMESPACE,  
38   STATE_ENUM,      /* 5 */    
39   STATE_BITFIELD,  
40   STATE_FUNCTION,   
41   STATE_FUNCTION_RETURN, 
42   STATE_FUNCTION_PARAMETERS,
43   STATE_FUNCTION_PARAMETER,  /* 10 */
44   STATE_CLASS,  
45   STATE_CLASS_FIELD,
46   STATE_CLASS_PROPERTY,
47   STATE_INTERFACE,
48   STATE_INTERFACE_PROPERTY,   /* 15 */
49   STATE_INTERFACE_FIELD,
50   STATE_IMPLEMENTS, 
51   STATE_REQUIRES,
52   STATE_BOXED,  
53   STATE_BOXED_FIELD, /* 20 */
54   STATE_STRUCT,   
55   STATE_STRUCT_FIELD,
56   STATE_ERRORDOMAIN, 
57   STATE_UNION,
58   STATE_UNION_FIELD, /* 25 */
59   STATE_NAMESPACE_CONSTANT, 
60   STATE_CLASS_CONSTANT, 
61   STATE_INTERFACE_CONSTANT,
62   STATE_ALIAS,
63   STATE_TYPE
64 } ParseState;
65
66 typedef struct _ParseContext ParseContext;
67 struct _ParseContext
68 {
69   ParseState state;
70   ParseState prev_state;
71
72   const char * const*includes;
73   
74   GList *modules;
75   GList *include_modules;
76   gboolean prefix_aliases;
77   GList *dependencies;
78   GHashTable *aliases;
79   GHashTable *disguised_structures;
80
81   const char *namespace;
82   GIrModule *current_module;
83   GIrNode *current_node;
84   GIrNode *current_typed;
85   gboolean is_varargs;
86   GList *type_stack;
87   GList *type_parameters;
88   int type_depth;
89 };
90
91 static void start_element_handler (GMarkupParseContext *context,
92                                    const gchar         *element_name,
93                                    const gchar        **attribute_names,
94                                    const gchar        **attribute_values,
95                                    gpointer             user_data,
96                                    GError             **error);
97 static void end_element_handler   (GMarkupParseContext *context,
98                                    const gchar         *element_name,
99                                    gpointer             user_data,
100                                    GError             **error);
101 static void text_handler          (GMarkupParseContext *context,
102                                    const gchar         *text,
103                                    gsize                text_len,
104                                    gpointer             user_data,
105                                    GError             **error);
106 static void cleanup               (GMarkupParseContext *context,
107                                    GError              *error,
108                                    gpointer             user_data);
109
110 static GMarkupParser parser = 
111 {
112   start_element_handler,
113   end_element_handler,
114   text_handler,
115   NULL,
116   cleanup
117 };
118
119 static gboolean
120 start_alias (GMarkupParseContext *context,
121              const gchar         *element_name,
122              const gchar        **attribute_names,
123              const gchar        **attribute_values,
124              ParseContext        *ctx,
125              GError             **error);
126
127 static const gchar *find_attribute (const gchar  *name, 
128                                     const gchar **attribute_names,
129                                     const gchar **attribute_values);
130
131 static void
132 firstpass_start_element_handler (GMarkupParseContext *context,
133                                  const gchar         *element_name,
134                                  const gchar        **attribute_names,
135                                  const gchar        **attribute_values,
136                                  gpointer             user_data,
137                                  GError             **error)
138 {
139   ParseContext *ctx = user_data;
140
141   if (strcmp (element_name, "alias") == 0) 
142     {
143       start_alias (context, element_name, attribute_names, attribute_values,
144                    ctx, error);
145     }
146   else if (strcmp (element_name, "record") == 0)
147     {
148       const gchar *name;
149       const gchar *disguised;
150
151       name = find_attribute ("name", attribute_names, attribute_values);
152       disguised = find_attribute ("disguised", attribute_names, attribute_values);
153
154       if (disguised && strcmp (disguised, "1") == 0)
155         {
156           char *key;
157
158           if (ctx->prefix_aliases)
159             {
160               key = g_strdup_printf ("%s.%s", ctx->namespace, name);
161             }
162           else
163             {
164               key = g_strdup (name);
165             }
166
167           g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
168         }
169     }
170 }
171
172 static void
173 firstpass_end_element_handler (GMarkupParseContext *context,
174                                const gchar         *element_name,
175                                gpointer             user_data,
176                                GError             **error)
177 {
178 }
179
180 static GMarkupParser firstpass_parser = 
181 {
182   firstpass_start_element_handler,
183   firstpass_end_element_handler,
184   NULL,
185   NULL,
186   NULL,
187 };
188
189 static char *
190 locate_gir (const char *name, const char *version, const char * const* extra_paths)
191 {
192   const gchar *const *datadirs;
193   const gchar *const *dir;
194   char *girname;
195   char *path = NULL;
196       
197   datadirs = g_get_system_data_dirs ();
198       
199   girname = g_strdup_printf ("%s-%s.gir", name, version);
200   
201   for (dir = datadirs; *dir; dir++) 
202     {
203       path = g_build_filename (*dir, "gir", girname, NULL);
204       if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
205         return path;
206       g_free (path);
207       path = NULL;
208     }
209   if (extra_paths != NULL)
210     {
211       for (dir = extra_paths; *dir; dir++) 
212         {
213           path = g_build_filename (*dir, girname, NULL);
214           if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
215             return path;
216           g_free (path);
217           path = NULL;
218         }
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   const gchar *offset;
873   GIrNodeField *field;
874
875   switch (ctx->state)
876     {
877     case STATE_CLASS:
878     case STATE_BOXED:
879     case STATE_STRUCT:
880     case STATE_UNION:
881     case STATE_INTERFACE:
882       break;
883     default:
884       return FALSE;
885     }
886   
887   if (strcmp (element_name, "field") != 0)
888     return FALSE;
889   
890   name = find_attribute ("name", attribute_names, attribute_values);
891   readable = find_attribute ("readable", attribute_names, attribute_values);
892   writable = find_attribute ("writable", attribute_names, attribute_values);
893   bits = find_attribute ("bits", attribute_names, attribute_values);
894   branch = find_attribute ("branch", attribute_names, attribute_values);
895   offset = find_attribute ("offset", attribute_names, attribute_values);
896   
897   if (name == NULL)
898     {
899       MISSING_ATTRIBUTE (context, error, element_name, "name");
900       return FALSE;
901     }
902
903   field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD);
904   ctx->current_typed = (GIrNode*) field;
905   ((GIrNode *)field)->name = g_strdup (name);
906   /* Fields are assumed to be read-only.
907    * (see also girwriter.py and generate.c)
908    */
909   field->readable = readable == NULL || strcmp (readable, "0") == 0;
910   field->writable = writable != NULL && strcmp (writable, "1") == 0;
911   
912   if (bits)
913     field->bits = atoi (bits);
914   else
915     field->bits = 0;
916   
917   if (offset)
918     field->offset = atoi (offset);
919   else
920     field->offset = 0;
921   
922   switch (ctx->current_node->type)
923     {
924     case G_IR_NODE_OBJECT:
925       {
926         GIrNodeInterface *iface;
927         
928         iface = (GIrNodeInterface *)ctx->current_node;
929         iface->members = g_list_append (iface->members, field);
930         state_switch (ctx, STATE_CLASS_FIELD);
931       }
932       break;
933     case G_IR_NODE_INTERFACE:
934       {
935         GIrNodeInterface *iface;
936         
937         iface = (GIrNodeInterface *)ctx->current_node;
938         iface->members = g_list_append (iface->members, field);
939         state_switch (ctx, STATE_INTERFACE_FIELD);
940       }
941       break;
942     case G_IR_NODE_BOXED:
943       {
944         GIrNodeBoxed *boxed;
945         
946         boxed = (GIrNodeBoxed *)ctx->current_node;
947                 boxed->members = g_list_append (boxed->members, field);
948                 state_switch (ctx, STATE_BOXED_FIELD);
949       }
950       break;
951     case G_IR_NODE_STRUCT:
952       {
953         GIrNodeStruct *struct_;
954         
955         struct_ = (GIrNodeStruct *)ctx->current_node;
956         struct_->members = g_list_append (struct_->members, field);
957         state_switch (ctx, STATE_STRUCT_FIELD);
958       }
959       break;
960     case G_IR_NODE_UNION:
961       {
962         GIrNodeUnion *union_;
963         
964         union_ = (GIrNodeUnion *)ctx->current_node;
965         union_->members = g_list_append (union_->members, field);
966         if (branch)
967           {
968             GIrNodeConstant *constant;
969             
970             constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
971             ((GIrNode *)constant)->name = g_strdup (name);
972             constant->value = g_strdup (branch);          
973             constant->type = union_->discriminator_type;
974             constant->deprecated = FALSE;
975             
976             union_->discriminators = g_list_append (union_->discriminators, constant);
977           }
978         state_switch (ctx, STATE_UNION_FIELD);
979       }
980       break;
981     default:
982       g_assert_not_reached ();
983     }
984   
985   return TRUE;
986 }
987
988 static gboolean
989 start_alias (GMarkupParseContext *context,
990              const gchar         *element_name,
991              const gchar        **attribute_names,
992              const gchar        **attribute_values,
993              ParseContext        *ctx,
994              GError             **error)
995 {
996   const gchar *name;
997   const gchar *target;
998   char *key;
999   char *value;
1000
1001   name = find_attribute ("name", attribute_names, attribute_values);
1002   if (name == NULL)
1003     {
1004       MISSING_ATTRIBUTE (context, error, element_name, "name");
1005       return FALSE;
1006     }
1007
1008   target = find_attribute ("target", attribute_names, attribute_values);
1009   if (name == NULL)
1010     {
1011       MISSING_ATTRIBUTE (context, error, element_name, "target");
1012       return FALSE;
1013     }
1014
1015   value = g_strdup (target);
1016   if (ctx->prefix_aliases)
1017     {
1018       key = g_strdup_printf ("%s.%s", ctx->namespace, name);
1019       if (!strchr (target, '.'))
1020         {
1021           const BasicTypeInfo *basic = parse_basic (target);
1022           if (!basic)
1023             {
1024               g_free (value);
1025               /* For non-basic types, re-qualify the interface */
1026               value = g_strdup_printf ("%s.%s", ctx->namespace, target);
1027             }
1028         }
1029     }
1030   else
1031     {
1032       key = g_strdup (name);
1033     }
1034   g_hash_table_insert (ctx->aliases, key, value);
1035
1036   return TRUE;
1037 }
1038
1039 static gboolean
1040 start_enum (GMarkupParseContext *context,
1041              const gchar         *element_name,
1042              const gchar        **attribute_names,
1043              const gchar        **attribute_values,
1044              ParseContext        *ctx,
1045              GError             **error)
1046 {
1047   if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
1048       (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))
1049     {
1050       const gchar *name;
1051       const gchar *typename;
1052       const gchar *typeinit;
1053       const gchar *deprecated;
1054       
1055       name = find_attribute ("name", attribute_names, attribute_values);
1056       typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1057       typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1058       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1059       
1060       if (name == NULL)
1061         MISSING_ATTRIBUTE (context, error, element_name, "name");
1062       else 
1063         {             
1064           GIrNodeEnum *enum_;
1065           
1066           if (strcmp (element_name, "enumeration") == 0)
1067             enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM);
1068           else
1069             enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS);
1070           ((GIrNode *)enum_)->name = g_strdup (name);
1071           enum_->gtype_name = g_strdup (typename);
1072           enum_->gtype_init = g_strdup (typeinit);
1073           if (deprecated)
1074             enum_->deprecated = TRUE;
1075           else
1076             enum_->deprecated = FALSE;
1077
1078           ctx->current_node = (GIrNode *) enum_;
1079           ctx->current_module->entries = 
1080             g_list_append (ctx->current_module->entries, enum_);              
1081           
1082           state_switch (ctx, STATE_ENUM);
1083         }
1084       
1085       return TRUE;
1086     }
1087   return FALSE;
1088 }
1089
1090 static gboolean
1091 start_property (GMarkupParseContext *context,
1092                 const gchar         *element_name,
1093                 const gchar        **attribute_names,
1094                 const gchar        **attribute_values,
1095                 ParseContext        *ctx,
1096                 GError             **error)
1097 {
1098   if (strcmp (element_name, "property") == 0 &&
1099       (ctx->state == STATE_CLASS ||
1100        ctx->state == STATE_INTERFACE))
1101     {
1102       const gchar *name;
1103       const gchar *readable;
1104       const gchar *writable;
1105       const gchar *construct;
1106       const gchar *construct_only;
1107       
1108       name = find_attribute ("name", attribute_names, attribute_values);
1109       readable = find_attribute ("readable", attribute_names, attribute_values);
1110       writable = find_attribute ("writable", attribute_names, attribute_values);
1111       construct = find_attribute ("construct", attribute_names, attribute_values);
1112       construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
1113       
1114       if (name == NULL)
1115         MISSING_ATTRIBUTE (context, error, element_name, "name");
1116       else 
1117         {             
1118           GIrNodeProperty *property;
1119           GIrNodeInterface *iface;
1120           
1121           property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
1122           ctx->current_typed = (GIrNode*) property;
1123
1124           ((GIrNode *)property)->name = g_strdup (name);
1125           
1126           /* Assume properties are readable */
1127           if (readable == NULL || strcmp (readable, "1") == 0)
1128             property->readable = TRUE;
1129           else
1130             property->readable = FALSE;
1131           if (writable && strcmp (writable, "1") == 0)
1132             property->writable = TRUE;
1133           else
1134             property->writable = FALSE;
1135           if (construct && strcmp (construct, "1") == 0)
1136             property->construct = TRUE;
1137           else
1138             property->construct = FALSE;
1139           if (construct_only && strcmp (construct_only, "1") == 0)
1140             property->construct_only = TRUE;
1141           else
1142             property->construct_only = FALSE;
1143
1144           iface = (GIrNodeInterface *)ctx->current_node;
1145           iface->members = g_list_append (iface->members, property);
1146
1147           if (ctx->state == STATE_CLASS)
1148             state_switch (ctx, STATE_CLASS_PROPERTY);
1149           else if (ctx->state == STATE_INTERFACE)
1150             state_switch (ctx, STATE_INTERFACE_PROPERTY);
1151           else
1152             g_assert_not_reached ();
1153         }
1154       
1155       return TRUE;
1156     }
1157   return FALSE;
1158 }
1159
1160 static gint
1161 parse_value (const gchar *str)
1162 {
1163   gchar *shift_op;
1164  
1165   /* FIXME just a quick hack */
1166   shift_op = strstr (str, "<<");
1167
1168   if (shift_op)
1169     {
1170       gint base, shift;
1171
1172       base = strtol (str, NULL, 10);
1173       shift = strtol (shift_op + 3, NULL, 10);
1174       
1175       return base << shift;
1176     }
1177   else
1178     return strtol (str, NULL, 10);
1179
1180   return 0;
1181 }
1182
1183 static gboolean
1184 start_member (GMarkupParseContext *context,
1185               const gchar         *element_name,
1186               const gchar        **attribute_names,
1187               const gchar        **attribute_values,
1188               ParseContext        *ctx,
1189               GError             **error)
1190 {
1191   if (strcmp (element_name, "member") == 0 &&
1192       ctx->state == STATE_ENUM)
1193     {
1194       const gchar *name;
1195       const gchar *value;
1196       const gchar *deprecated;
1197       
1198       name = find_attribute ("name", attribute_names, attribute_values);
1199       value = find_attribute ("value", attribute_names, attribute_values);
1200       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1201       
1202       if (name == NULL)
1203         MISSING_ATTRIBUTE (context, error, element_name, "name");
1204       else 
1205         {             
1206           GIrNodeEnum *enum_;
1207           GIrNodeValue *value_;
1208
1209           value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
1210
1211           ((GIrNode *)value_)->name = g_strdup (name);
1212           
1213           value_->value = parse_value (value);
1214           
1215           if (deprecated)
1216             value_->deprecated = TRUE;
1217           else
1218             value_->deprecated = FALSE;
1219
1220           enum_ = (GIrNodeEnum *)ctx->current_node;
1221           enum_->values = g_list_append (enum_->values, value_);
1222         }
1223       
1224       return TRUE;
1225     }
1226   return FALSE;
1227 }
1228
1229 static gboolean
1230 start_constant (GMarkupParseContext *context,
1231                 const gchar         *element_name,
1232                 const gchar        **attribute_names,
1233                 const gchar        **attribute_values,
1234                 ParseContext        *ctx,
1235                 GError             **error)
1236 {
1237   if (strcmp (element_name, "constant") == 0 &&
1238       (ctx->state == STATE_NAMESPACE ||
1239        ctx->state == STATE_CLASS ||
1240        ctx->state == STATE_INTERFACE))
1241     {
1242       const gchar *name;
1243       const gchar *value;
1244       const gchar *deprecated;
1245       
1246       name = find_attribute ("name", attribute_names, attribute_values);
1247       value = find_attribute ("value", attribute_names, attribute_values);
1248       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1249       
1250       if (name == NULL)
1251         MISSING_ATTRIBUTE (context, error, element_name, "name");
1252       else if (value == NULL)
1253         MISSING_ATTRIBUTE (context, error, element_name, "value");
1254       else 
1255         {             
1256           GIrNodeConstant *constant;
1257
1258           constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1259
1260           ((GIrNode *)constant)->name = g_strdup (name);
1261           constant->value = g_strdup (value);
1262
1263           ctx->current_typed = (GIrNode*) constant;
1264
1265           if (deprecated)
1266             constant->deprecated = TRUE;
1267           else
1268             constant->deprecated = FALSE;
1269
1270           if (ctx->state == STATE_NAMESPACE)
1271             {
1272               ctx->current_node = (GIrNode *) constant;
1273               ctx->current_module->entries = 
1274                 g_list_append (ctx->current_module->entries, constant);
1275             }
1276           else
1277             {
1278               GIrNodeInterface *iface;
1279
1280               iface = (GIrNodeInterface *)ctx->current_node;
1281               iface->members = g_list_append (iface->members, constant);
1282             }
1283
1284           switch (ctx->state)
1285             {
1286             case STATE_NAMESPACE:
1287               state_switch (ctx, STATE_NAMESPACE_CONSTANT);
1288               break;
1289             case STATE_CLASS:
1290               state_switch (ctx, STATE_CLASS_CONSTANT);
1291               break;
1292             case STATE_INTERFACE:
1293               state_switch (ctx, STATE_INTERFACE_CONSTANT);
1294               break;
1295             default:
1296               g_assert_not_reached ();
1297               break;
1298             }
1299         }
1300       
1301       return TRUE;
1302     }
1303   return FALSE;
1304 }
1305
1306 static gboolean
1307 start_errordomain (GMarkupParseContext *context,
1308                    const gchar         *element_name,
1309                    const gchar        **attribute_names,
1310                    const gchar        **attribute_values,
1311                    ParseContext        *ctx,
1312                    GError             **error)
1313 {
1314   if (strcmp (element_name, "errordomain") == 0 &&
1315       ctx->state == STATE_NAMESPACE)
1316     {
1317       const gchar *name;
1318       const gchar *getquark;
1319       const gchar *codes;
1320       const gchar *deprecated;
1321       
1322       name = find_attribute ("name", attribute_names, attribute_values);
1323       getquark = find_attribute ("get-quark", attribute_names, attribute_values);
1324       codes = find_attribute ("codes", attribute_names, attribute_values);
1325       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1326       
1327       if (name == NULL)
1328         MISSING_ATTRIBUTE (context, error, element_name, "name");
1329       else if (getquark == NULL)
1330         MISSING_ATTRIBUTE (context, error, element_name, "getquark");
1331       else if (codes == NULL)
1332         MISSING_ATTRIBUTE (context, error, element_name, "codes");
1333       else 
1334         {             
1335           GIrNodeErrorDomain *domain;
1336
1337           domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
1338
1339           ((GIrNode *)domain)->name = g_strdup (name);
1340           domain->getquark = g_strdup (getquark);
1341           domain->codes = g_strdup (codes);
1342
1343           if (deprecated)
1344             domain->deprecated = TRUE;
1345           else
1346             domain->deprecated = FALSE;
1347
1348           ctx->current_node = (GIrNode *) domain;
1349           ctx->current_module->entries = 
1350             g_list_append (ctx->current_module->entries, domain);
1351
1352           state_switch (ctx, STATE_ERRORDOMAIN);
1353         }
1354       
1355       return TRUE;
1356     }
1357   return FALSE;
1358 }
1359
1360 static gboolean
1361 start_interface (GMarkupParseContext *context,
1362                  const gchar         *element_name,
1363                  const gchar        **attribute_names,
1364                  const gchar        **attribute_values,
1365                  ParseContext        *ctx,
1366                  GError             **error)
1367 {
1368   if (strcmp (element_name, "interface") == 0 &&
1369       ctx->state == STATE_NAMESPACE)
1370     {
1371       const gchar *name;
1372       const gchar *typename;
1373       const gchar *typeinit;
1374       const gchar *deprecated;
1375       
1376       name = find_attribute ("name", attribute_names, attribute_values);
1377       typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1378       typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1379       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1380       
1381       if (name == NULL)
1382         MISSING_ATTRIBUTE (context, error, element_name, "name");
1383       else if (typename == NULL)
1384         MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1385       else if (typeinit == NULL)
1386         MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1387       else
1388         {
1389           GIrNodeInterface *iface;
1390
1391           iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE);
1392           ((GIrNode *)iface)->name = g_strdup (name);
1393           iface->gtype_name = g_strdup (typename);
1394           iface->gtype_init = g_strdup (typeinit);
1395           if (deprecated)
1396             iface->deprecated = TRUE;
1397           else
1398             iface->deprecated = FALSE;
1399           
1400           ctx->current_node = (GIrNode *) iface;
1401           ctx->current_module->entries = 
1402             g_list_append (ctx->current_module->entries, iface);              
1403           
1404           state_switch (ctx, STATE_INTERFACE);
1405           
1406         }
1407       
1408       return TRUE;
1409     }
1410   return FALSE;
1411 }
1412
1413 static gboolean
1414 start_class (GMarkupParseContext *context,
1415               const gchar         *element_name,
1416               const gchar        **attribute_names,
1417               const gchar        **attribute_values,
1418               ParseContext        *ctx,
1419               GError             **error)
1420 {
1421   if (strcmp (element_name, "class") == 0 &&
1422       ctx->state == STATE_NAMESPACE)
1423     {
1424       const gchar *name;
1425       const gchar *parent;
1426       const gchar *typename;
1427       const gchar *typeinit;
1428       const gchar *deprecated;
1429       const gchar *abstract;
1430       
1431       name = find_attribute ("name", attribute_names, attribute_values);
1432       parent = find_attribute ("parent", attribute_names, attribute_values);
1433       typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1434       typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1435       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1436       abstract = find_attribute ("abstract", attribute_names, attribute_values);
1437       
1438       if (name == NULL)
1439         MISSING_ATTRIBUTE (context, error, element_name, "name");
1440       else if (typename == NULL)
1441         MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1442       else if (typeinit == NULL && strcmp (typename, "GObject"))
1443         MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1444       else
1445         {
1446           GIrNodeInterface *iface;
1447
1448           iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT);
1449           ((GIrNode *)iface)->name = g_strdup (name);
1450           iface->gtype_name = g_strdup (typename);
1451           iface->gtype_init = g_strdup (typeinit);
1452           iface->parent = g_strdup (parent);
1453           if (deprecated)
1454             iface->deprecated = TRUE;
1455           else
1456             iface->deprecated = FALSE;
1457
1458           iface->abstract = abstract && strcmp (abstract, "1") == 0;
1459
1460           ctx->current_node = (GIrNode *) iface;
1461           ctx->current_module->entries = 
1462             g_list_append (ctx->current_module->entries, iface);              
1463           
1464           state_switch (ctx, STATE_CLASS);
1465         }
1466       
1467       return TRUE;
1468     }
1469   return  FALSE;
1470 }
1471
1472 static gboolean
1473 start_type (GMarkupParseContext *context,
1474             const gchar         *element_name,
1475             const gchar        **attribute_names,
1476             const gchar        **attribute_values,
1477             ParseContext       *ctx,
1478             GError             **error)
1479 {
1480   const gchar *name;
1481   const gchar *ctype;
1482   gboolean is_array;
1483   gboolean is_varargs;
1484   GIrNodeType *typenode;
1485
1486   is_array = strcmp (element_name, "array") == 0;
1487   is_varargs = strcmp (element_name, "varargs") == 0;
1488
1489   if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
1490     return FALSE;
1491
1492   if (ctx->state == STATE_TYPE) 
1493     {
1494       ctx->type_depth++;
1495       ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters);
1496       ctx->type_parameters = NULL;
1497     } 
1498   else if (ctx->state == STATE_FUNCTION_PARAMETER ||
1499            ctx->state == STATE_FUNCTION_RETURN || 
1500            ctx->state == STATE_STRUCT_FIELD ||
1501            ctx->state == STATE_UNION_FIELD ||
1502            ctx->state == STATE_CLASS_PROPERTY ||
1503            ctx->state == STATE_CLASS_FIELD ||
1504            ctx->state == STATE_INTERFACE_FIELD ||
1505            ctx->state == STATE_INTERFACE_PROPERTY ||
1506            ctx->state == STATE_BOXED_FIELD ||
1507            ctx->state == STATE_NAMESPACE_CONSTANT ||
1508            ctx->state == STATE_CLASS_CONSTANT ||
1509            ctx->state == STATE_INTERFACE_CONSTANT
1510            )
1511     {
1512       state_switch (ctx, STATE_TYPE);
1513       ctx->type_depth = 1;
1514       if (is_varargs)
1515         {
1516           switch (ctx->current_node->type)
1517             {
1518             case G_IR_NODE_FUNCTION:
1519             case G_IR_NODE_CALLBACK:
1520               {
1521                 GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
1522                 func->is_varargs = TRUE;
1523               }
1524               break;
1525             case G_IR_NODE_VFUNC:
1526               {
1527                 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
1528                 vfunc->is_varargs = TRUE;
1529               }
1530               break;
1531             /* list others individually rather than with default: so that compiler
1532              * warns if new node types are added without adding them to the switch
1533              */
1534             case G_IR_NODE_INVALID:
1535             case G_IR_NODE_ENUM:
1536             case G_IR_NODE_FLAGS:
1537             case G_IR_NODE_CONSTANT:
1538             case G_IR_NODE_ERROR_DOMAIN:
1539             case G_IR_NODE_PARAM:
1540             case G_IR_NODE_TYPE:
1541             case G_IR_NODE_PROPERTY:
1542             case G_IR_NODE_SIGNAL:
1543             case G_IR_NODE_VALUE:
1544             case G_IR_NODE_FIELD:
1545             case G_IR_NODE_XREF:
1546             case G_IR_NODE_STRUCT:
1547             case G_IR_NODE_BOXED:
1548             case G_IR_NODE_OBJECT:
1549             case G_IR_NODE_INTERFACE:
1550             case G_IR_NODE_UNION:
1551               g_assert_not_reached ();
1552               break;
1553             }
1554         }
1555       ctx->type_stack = NULL;
1556       ctx->type_parameters = NULL;
1557     }
1558
1559   if (!ctx->current_typed)
1560     {
1561       g_set_error (error,
1562                    G_MARKUP_ERROR,
1563                    G_MARKUP_ERROR_INVALID_CONTENT,
1564                    "The element <type> is invalid here");
1565       return FALSE;
1566     }
1567
1568   if (is_varargs)
1569     return TRUE;
1570
1571   if (is_array) 
1572     {
1573       const char *zero;
1574       const char *len;
1575       const char *size;
1576
1577       typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
1578
1579       typenode->tag = GI_TYPE_TAG_ARRAY;
1580       typenode->is_pointer = TRUE;
1581       typenode->is_array = TRUE;
1582       
1583       zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
1584       len = find_attribute ("length", attribute_names, attribute_values);
1585       size = find_attribute ("fixed-size", attribute_names, attribute_values);
1586       
1587       typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0);
1588       typenode->has_length = len != NULL;
1589       typenode->length = typenode->has_length ? atoi (len) : -1;
1590       
1591       typenode->has_size = size != NULL;
1592       typenode->size = typenode->has_size ? atoi (size) : -1;
1593     }
1594   else
1595     {
1596       gboolean is_pointer;
1597       name = find_attribute ("name", attribute_names, attribute_values);
1598
1599       if (name == NULL)
1600         MISSING_ATTRIBUTE (context, error, element_name, "name");
1601       
1602       ctype = find_attribute ("c:type", attribute_names, attribute_values);
1603       if (ctype != NULL && strchr (ctype, '*'))
1604         is_pointer = TRUE;
1605       else
1606         is_pointer = FALSE;
1607
1608       typenode = parse_type (ctx, name);
1609
1610       /* A 'disguised' structure is one where the c:type is a typedef that
1611        * doesn't look like a pointer, but is internally.
1612        */
1613       if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
1614           g_hash_table_lookup (ctx->disguised_structures, typenode->interface) != NULL)
1615         is_pointer = TRUE;
1616
1617       if (is_pointer)
1618         typenode->is_pointer = is_pointer;
1619     }
1620
1621   ctx->type_parameters = g_list_append (ctx->type_parameters, typenode);
1622   
1623   return TRUE;
1624 }
1625
1626 static void
1627 end_type_top (ParseContext *ctx)
1628 {
1629   GIrNodeType *typenode;
1630
1631   if (!ctx->type_parameters)
1632     goto out;
1633
1634   typenode = (GIrNodeType*)ctx->type_parameters->data;
1635
1636   /* Default to pointer for unspecified containers */
1637   if (typenode->tag == GI_TYPE_TAG_ARRAY ||
1638       typenode->tag == GI_TYPE_TAG_GLIST ||
1639       typenode->tag == GI_TYPE_TAG_GSLIST)
1640     {
1641       if (typenode->parameter_type1 == NULL)
1642         typenode->parameter_type1 = parse_type (ctx, "any");
1643     }
1644   else if (typenode->tag == GI_TYPE_TAG_GHASH)
1645     {
1646       if (typenode->parameter_type1 == NULL)
1647         {
1648           typenode->parameter_type1 = parse_type (ctx, "any");
1649           typenode->parameter_type2 = parse_type (ctx, "any");
1650         }
1651     }
1652
1653   switch (ctx->current_typed->type)
1654     {
1655     case G_IR_NODE_PARAM:
1656       {
1657         GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed;
1658         param->type = typenode;
1659       }
1660       break;
1661     case G_IR_NODE_FIELD:
1662       {
1663         GIrNodeField *field = (GIrNodeField *)ctx->current_typed;
1664         field->type = typenode;
1665       }
1666       break;
1667     case G_IR_NODE_PROPERTY:
1668       {
1669         GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed;
1670         property->type = typenode;
1671       }
1672       break;
1673     case G_IR_NODE_CONSTANT:
1674       {
1675         GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed;
1676         constant->type = typenode;
1677       }
1678       break;
1679     default:
1680       g_printerr("current node is %d\n", ctx->current_node->type);
1681       g_assert_not_reached ();
1682     }
1683   g_list_free (ctx->type_parameters);
1684
1685  out:  
1686   ctx->type_depth = 0;
1687   ctx->type_parameters = NULL;
1688   ctx->current_typed = NULL;
1689 }
1690
1691 static void
1692 end_type_recurse (ParseContext *ctx)
1693 {
1694   GIrNodeType *parent;
1695   GIrNodeType *param = NULL;
1696
1697   parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data;
1698   if (ctx->type_parameters)
1699     param = (GIrNodeType *) ctx->type_parameters->data;
1700
1701   if (parent->tag == GI_TYPE_TAG_ARRAY ||
1702       parent->tag == GI_TYPE_TAG_GLIST ||
1703       parent->tag == GI_TYPE_TAG_GSLIST)
1704     {
1705       g_assert (param != NULL);
1706
1707       if (parent->parameter_type1 == NULL)
1708         parent->parameter_type1 = param;
1709       else
1710         g_assert_not_reached ();
1711     }
1712   else if (parent->tag == GI_TYPE_TAG_GHASH)
1713     {
1714       g_assert (param != NULL);
1715
1716       if (parent->parameter_type1 == NULL)
1717         parent->parameter_type1 = param;
1718       else if (parent->parameter_type2 == NULL)
1719         parent->parameter_type2 = param;
1720       else
1721         g_assert_not_reached ();
1722     }
1723   g_list_free (ctx->type_parameters);
1724   ctx->type_parameters = (GList *)ctx->type_stack->data;
1725   ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
1726 }
1727
1728 static void
1729 end_type (ParseContext *ctx)
1730 {
1731   if (ctx->type_depth == 1)
1732     {
1733       end_type_top (ctx);
1734       state_switch (ctx, ctx->prev_state);
1735     }
1736   else
1737     {
1738       end_type_recurse (ctx);
1739       ctx->type_depth--;
1740     }
1741 }
1742
1743 static gboolean
1744 start_return_value (GMarkupParseContext *context,
1745                     const gchar         *element_name,
1746                     const gchar        **attribute_names,
1747                     const gchar        **attribute_values,
1748                     ParseContext       *ctx,
1749                     GError             **error)
1750 {
1751   if (strcmp (element_name, "return-value") == 0 &&
1752       ctx->state == STATE_FUNCTION)
1753     {
1754       GIrNodeParam *param;
1755       const gchar  *transfer;
1756
1757       param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
1758       param->in = FALSE;
1759       param->out = FALSE;
1760       param->retval = TRUE;
1761
1762       ctx->current_typed = (GIrNode*) param;
1763
1764       state_switch (ctx, STATE_FUNCTION_RETURN);
1765
1766       transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1767       parse_param_transfer (param, transfer);
1768
1769       switch (ctx->current_node->type)
1770         {
1771         case G_IR_NODE_FUNCTION:
1772         case G_IR_NODE_CALLBACK:
1773           {
1774             GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
1775             func->result = param;
1776           }
1777           break;
1778         case G_IR_NODE_SIGNAL:
1779           {
1780             GIrNodeSignal *signal = (GIrNodeSignal *)ctx->current_node;
1781             signal->result = param;
1782           }
1783           break;
1784         case G_IR_NODE_VFUNC:
1785           {
1786             GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
1787             vfunc->result = param;
1788           }
1789           break;
1790         default:
1791           g_assert_not_reached ();
1792         }
1793       
1794       return TRUE;
1795     }
1796
1797   return FALSE;
1798 }
1799
1800 static gboolean
1801 start_implements (GMarkupParseContext *context,
1802                   const gchar         *element_name,
1803                   const gchar        **attribute_names,
1804                   const gchar        **attribute_values,
1805                   ParseContext       *ctx,
1806                   GError             **error)
1807 {
1808   GIrNodeInterface *iface;
1809   const char *name;
1810
1811   if (strcmp (element_name, "implements") != 0 ||
1812       !(ctx->state == STATE_CLASS))
1813     return FALSE;
1814
1815   state_switch (ctx, STATE_IMPLEMENTS);
1816   
1817   name = find_attribute ("name", attribute_names, attribute_values);
1818   if (name == NULL)
1819     {
1820       MISSING_ATTRIBUTE (context, error, element_name, "name");
1821       return FALSE;
1822     }
1823       
1824   iface = (GIrNodeInterface *)ctx->current_node;
1825   iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
1826
1827   return TRUE;
1828 }
1829
1830 static gboolean
1831 start_glib_signal (GMarkupParseContext *context,
1832                    const gchar         *element_name,
1833                    const gchar        **attribute_names,
1834                    const gchar        **attribute_values,
1835                    ParseContext       *ctx,
1836                    GError             **error)
1837 {
1838   if (strcmp (element_name, "glib:signal") == 0 && 
1839       (ctx->state == STATE_CLASS ||
1840        ctx->state == STATE_INTERFACE))
1841     {
1842       const gchar *name;
1843       const gchar *when;
1844       const gchar *no_recurse;
1845       const gchar *detailed;
1846       const gchar *action;
1847       const gchar *no_hooks;
1848       const gchar *has_class_closure;
1849       
1850       name = find_attribute ("name", attribute_names, attribute_values);
1851       when = find_attribute ("when", attribute_names, attribute_values);
1852       no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values);
1853       detailed = find_attribute ("detailed", attribute_names, attribute_values);
1854       action = find_attribute ("action", attribute_names, attribute_values);
1855       no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values);
1856       has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values);
1857       
1858       if (name == NULL)
1859         MISSING_ATTRIBUTE (context, error, element_name, "name");
1860       else
1861         {
1862           GIrNodeInterface *iface;
1863           GIrNodeSignal *signal;
1864
1865           signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
1866           
1867           ((GIrNode *)signal)->name = g_strdup (name);
1868           
1869           signal->run_first = FALSE;
1870           signal->run_last = FALSE;
1871           signal->run_cleanup = FALSE;
1872           if (when == NULL || strcmp (when, "LAST") == 0)
1873             signal->run_last = TRUE;
1874           else if (strcmp (when, "FIRST") == 0)
1875             signal->run_first = TRUE;
1876           else 
1877             signal->run_cleanup = TRUE;
1878           
1879           if (no_recurse && strcmp (no_recurse, "1") == 0)
1880             signal->no_recurse = TRUE;
1881           else
1882             signal->no_recurse = FALSE;
1883           if (detailed && strcmp (detailed, "1") == 0)
1884             signal->detailed = TRUE;
1885           else
1886             signal->detailed = FALSE;
1887           if (action && strcmp (action, "1") == 0)
1888             signal->action = TRUE;
1889           else
1890             signal->action = FALSE;
1891           if (no_hooks && strcmp (no_hooks, "1") == 0)
1892             signal->no_hooks = TRUE;
1893           else
1894             signal->no_hooks = FALSE;
1895           if (has_class_closure && strcmp (has_class_closure, "1") == 0)
1896             signal->has_class_closure = TRUE;
1897           else
1898             signal->has_class_closure = FALSE;
1899
1900           iface = (GIrNodeInterface *)ctx->current_node;
1901           iface->members = g_list_append (iface->members, signal);
1902
1903           ctx->current_node = (GIrNode *)signal;
1904           state_switch (ctx, STATE_FUNCTION);
1905         }
1906       
1907       return TRUE;
1908     }
1909   return FALSE;
1910 }
1911
1912 static gboolean
1913 start_vfunc (GMarkupParseContext *context,
1914              const gchar         *element_name,
1915              const gchar        **attribute_names,
1916              const gchar        **attribute_values,
1917              ParseContext       *ctx,
1918              GError             **error)
1919 {
1920   if (strcmp (element_name, "vfunc") == 0 && 
1921       (ctx->state == STATE_CLASS ||
1922        ctx->state == STATE_INTERFACE))
1923     {
1924       const gchar *name;
1925       const gchar *must_chain_up;
1926       const gchar *override;
1927       const gchar *is_class_closure;
1928       const gchar *offset;
1929       
1930       name = find_attribute ("name", attribute_names, attribute_values);
1931       must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values);        
1932       override = find_attribute ("override", attribute_names, attribute_values);
1933       is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values);
1934       offset = find_attribute ("offset", attribute_names, attribute_values);
1935       
1936       if (name == NULL)
1937         MISSING_ATTRIBUTE (context, error, element_name, "name");
1938       else
1939         {
1940           GIrNodeInterface *iface;
1941           GIrNodeVFunc *vfunc;
1942
1943           vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
1944           
1945           ((GIrNode *)vfunc)->name = g_strdup (name);
1946
1947           if (must_chain_up && strcmp (must_chain_up, "1") == 0)
1948             vfunc->must_chain_up = TRUE;
1949           else
1950             vfunc->must_chain_up = FALSE;
1951
1952           if (override && strcmp (override, "always") == 0)
1953             {
1954               vfunc->must_be_implemented = TRUE;
1955               vfunc->must_not_be_implemented = FALSE;
1956             }
1957           else if (override && strcmp (override, "never") == 0)
1958             {
1959               vfunc->must_be_implemented = FALSE;
1960               vfunc->must_not_be_implemented = TRUE;
1961             }
1962           else
1963             {
1964               vfunc->must_be_implemented = FALSE;
1965               vfunc->must_not_be_implemented = FALSE;
1966             }
1967           
1968           if (is_class_closure && strcmp (is_class_closure, "1") == 0)
1969             vfunc->is_class_closure = TRUE;
1970           else
1971             vfunc->is_class_closure = FALSE;
1972           
1973           if (offset)
1974             vfunc->offset = atoi (offset);
1975           else
1976             vfunc->offset = 0;
1977
1978           iface = (GIrNodeInterface *)ctx->current_node;
1979           iface->members = g_list_append (iface->members, vfunc);
1980
1981           ctx->current_node = (GIrNode *)vfunc;
1982           state_switch (ctx, STATE_FUNCTION);
1983         }
1984       
1985       return TRUE;
1986     }
1987   return FALSE;
1988 }
1989
1990
1991 static gboolean
1992 start_struct (GMarkupParseContext *context,
1993               const gchar         *element_name,
1994               const gchar        **attribute_names,
1995               const gchar        **attribute_values,
1996               ParseContext       *ctx,
1997               GError             **error)
1998 {
1999   if (strcmp (element_name, "record") == 0 && 
2000       ctx->state == STATE_NAMESPACE)
2001     {
2002       const gchar *name;
2003       const gchar *deprecated;
2004       const gchar *disguised;
2005       const gchar *gtype_name;
2006       const gchar *gtype_init;
2007       GIrNodeStruct *struct_;
2008       
2009       name = find_attribute ("name", attribute_names, attribute_values);
2010       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2011       disguised = find_attribute ("disguised", attribute_names, attribute_values);
2012       gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
2013       gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
2014
2015       if (name == NULL)
2016         {
2017           MISSING_ATTRIBUTE (context, error, element_name, "name");
2018           return FALSE;
2019         }
2020       if ((gtype_name == NULL && gtype_init != NULL))
2021         {
2022           MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
2023           return FALSE;
2024         }
2025       if ((gtype_name != NULL && gtype_init == NULL))
2026         {
2027           MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
2028           return FALSE;
2029         }
2030
2031       struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
2032       
2033       ((GIrNode *)struct_)->name = g_strdup (name);
2034       if (deprecated)
2035         struct_->deprecated = TRUE;
2036       else
2037         struct_->deprecated = FALSE;
2038
2039       if (disguised && strcmp (disguised, "1") == 0)
2040         struct_->disguised = TRUE;
2041
2042       struct_->gtype_name = g_strdup (gtype_name);
2043       struct_->gtype_init = g_strdup (gtype_init);
2044       
2045       ctx->current_node = (GIrNode *)struct_;
2046       ctx->current_module->entries = 
2047         g_list_append (ctx->current_module->entries, struct_);
2048       
2049       state_switch (ctx, STATE_STRUCT);
2050       return TRUE;
2051     }
2052   return FALSE;
2053 }
2054   
2055
2056 static gboolean
2057 start_union (GMarkupParseContext *context,
2058              const gchar         *element_name,
2059              const gchar        **attribute_names,
2060              const gchar        **attribute_values,
2061              ParseContext       *ctx,
2062              GError             **error)
2063 {
2064   if (strcmp (element_name, "union") == 0 && 
2065       ctx->state == STATE_NAMESPACE)
2066     {
2067       const gchar *name;
2068       const gchar *deprecated;
2069       const gchar *typename;
2070       const gchar *typeinit;
2071       
2072       name = find_attribute ("name", attribute_names, attribute_values);
2073       deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2074       typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
2075       typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
2076       
2077       if (name == NULL)
2078         MISSING_ATTRIBUTE (context, error, element_name, "name");
2079       else
2080         {
2081           GIrNodeUnion *union_;
2082
2083           union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
2084           
2085           ((GIrNode *)union_)->name = g_strdup (name);
2086           union_->gtype_name = g_strdup (typename);
2087           union_->gtype_init = g_strdup (typeinit);
2088           if (deprecated)
2089             union_->deprecated = TRUE;
2090           else
2091             union_->deprecated = FALSE;
2092
2093           ctx->current_node = (GIrNode *)union_;
2094           ctx->current_module->entries = 
2095             g_list_append (ctx->current_module->entries, union_);
2096           
2097           state_switch (ctx, STATE_UNION);
2098         }
2099       return TRUE;
2100     }
2101   return FALSE;
2102 }
2103
2104 static gboolean
2105 start_discriminator (GMarkupParseContext *context,
2106                      const gchar         *element_name,
2107                      const gchar        **attribute_names,
2108                      const gchar        **attribute_values,
2109                      ParseContext       *ctx,
2110                      GError             **error)
2111 {
2112   if (strcmp (element_name, "discriminator") == 0 &&
2113       ctx->state == STATE_UNION)
2114     {
2115       const gchar *type;
2116       const gchar *offset;
2117       
2118       type = find_attribute ("type", attribute_names, attribute_values);
2119       offset = find_attribute ("offset", attribute_names, attribute_values);
2120       if (type == NULL)
2121         MISSING_ATTRIBUTE (context, error, element_name, "type");
2122       else if (offset == NULL)
2123         MISSING_ATTRIBUTE (context, error, element_name, "offset");
2124         {
2125           ((GIrNodeUnion *)ctx->current_node)->discriminator_type 
2126             = parse_type (ctx, type);
2127           ((GIrNodeUnion *)ctx->current_node)->discriminator_offset 
2128             = atoi (offset);
2129         }
2130       
2131       return TRUE;
2132     }
2133
2134   return FALSE;
2135 }
2136
2137 static gboolean
2138 parse_include (GMarkupParseContext *context,
2139                ParseContext        *ctx,
2140                const char          *name,
2141                const char          *version,
2142                GError             **error)
2143 {
2144   ParseContext sub_ctx = { 0 };
2145   gchar *buffer;
2146   gsize length;
2147   char *girpath;
2148   gboolean success = FALSE;
2149   GList *l;
2150
2151   for (l = ctx->include_modules; l; l = l->next)
2152     {
2153       GIrModule *m = l->data;
2154
2155       if (strcmp (m->name, name) == 0)
2156         {
2157           if (strcmp (m->version, version) == 0)
2158             {
2159               return TRUE;
2160             }
2161           else
2162             {
2163               g_set_error (error,
2164                            G_MARKUP_ERROR,
2165                            G_MARKUP_ERROR_INVALID_CONTENT,
2166                            "Module '%s' imported with conflicting versions '%s' and '%s'",
2167                            name, m->version, version);
2168               return FALSE;
2169             }
2170         }
2171     }
2172
2173   girpath = locate_gir (name, version, ctx->includes);
2174
2175   if (girpath == NULL)
2176     {
2177       g_set_error (error,
2178                    G_MARKUP_ERROR,
2179                    G_MARKUP_ERROR_INVALID_CONTENT,
2180                    "Could not find GIR file '%s.gir'; check XDG_DATA_DIRS or use --includedir",
2181                    name);
2182       return FALSE;
2183     }
2184
2185   g_debug ("Parsing include %s", girpath);
2186
2187   if (!g_file_get_contents (girpath, &buffer, &length, error))
2188     {
2189       g_free (girpath);
2190       return FALSE;
2191     }
2192   g_free (girpath);
2193
2194   sub_ctx.state = STATE_START;
2195   sub_ctx.includes = ctx->includes;
2196   sub_ctx.prefix_aliases = TRUE;
2197   sub_ctx.namespace = name;
2198   sub_ctx.aliases = ctx->aliases;
2199   sub_ctx.disguised_structures = ctx->disguised_structures;
2200   sub_ctx.type_depth = 0;
2201
2202   context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL);
2203
2204   if (!g_markup_parse_context_parse (context, buffer, length, error))
2205     goto out;
2206
2207   if (!g_markup_parse_context_end_parse (context, error))
2208     goto out;
2209
2210   g_markup_parse_context_free (context);
2211
2212   context = g_markup_parse_context_new (&parser, 0, &sub_ctx, NULL);
2213   if (!g_markup_parse_context_parse (context, buffer, length, error))
2214     goto out;
2215
2216   if (!g_markup_parse_context_end_parse (context, error))
2217     goto out;
2218
2219   success = TRUE;
2220
2221  out:
2222   ctx->include_modules = g_list_concat (ctx->include_modules,
2223                                         sub_ctx.modules);
2224
2225   g_markup_parse_context_free (context);
2226   g_free (buffer);
2227
2228   return success;
2229 }
2230   
2231 extern GLogLevelFlags logged_levels;
2232
2233 static void
2234 start_element_handler (GMarkupParseContext *context,
2235                        const gchar         *element_name,
2236                        const gchar        **attribute_names,
2237                        const gchar        **attribute_values,
2238                        gpointer             user_data,
2239                        GError             **error)
2240 {
2241   ParseContext *ctx = user_data;
2242   gint line_number, char_number;
2243
2244   if (logged_levels & G_LOG_LEVEL_DEBUG)
2245     {
2246       GString *tags = g_string_new ("");
2247       int i;
2248       for (i = 0; attribute_names[i]; i++)
2249         g_string_append_printf (tags, "%s=\"%s\" ",
2250                                 attribute_names[i],
2251                                 attribute_values[i]);
2252
2253       if (i)
2254         {
2255           g_string_insert_c (tags, 0, ' ');
2256           g_string_truncate (tags, tags->len - 1);
2257         }
2258       g_debug ("<%s%s>", element_name, tags->str);
2259       g_string_free (tags, TRUE);
2260     }
2261
2262   switch (element_name[0]) 
2263     {
2264     case 'a':
2265       if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0) 
2266         {
2267           state_switch (ctx, STATE_ALIAS);
2268           goto out;
2269         }
2270       if (start_type (context, element_name,
2271                       attribute_names, attribute_values,
2272                       ctx, error))
2273         goto out;
2274       break;
2275     case 'b':
2276       if (start_enum (context, element_name, 
2277                       attribute_names, attribute_values,
2278                       ctx, error))
2279         goto out;
2280       break;
2281     case 'c':
2282       if (start_function (context, element_name, 
2283                           attribute_names, attribute_values,
2284                           ctx, error))
2285         goto out;
2286       else if (start_constant (context, element_name,
2287                                attribute_names, attribute_values,
2288                                ctx, error))
2289         goto out;
2290       else if (start_class (context, element_name, 
2291                             attribute_names, attribute_values,
2292                             ctx, error))
2293         goto out;
2294       else if (strcmp (element_name, "class") == 0 &&
2295                ctx->state == STATE_REQUIRES)
2296         {
2297           const gchar *name;
2298
2299           name = find_attribute ("name", attribute_names, attribute_values);
2300
2301           if (name == NULL)
2302             MISSING_ATTRIBUTE (context, error, element_name, "name");
2303           else
2304             {  
2305               GIrNodeInterface *iface;
2306
2307               iface = (GIrNodeInterface *)ctx->current_node;
2308               iface ->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
2309             }
2310
2311           goto out;
2312         }
2313       break;
2314
2315     case 'd':
2316       if (start_discriminator (context, element_name, 
2317                                attribute_names, attribute_values,
2318                                ctx, error))
2319         goto out;
2320       break;
2321
2322     case 'e':
2323       if (start_enum (context, element_name, 
2324                       attribute_names, attribute_values,
2325                       ctx, error))
2326         goto out;
2327       else if (start_errordomain (context, element_name, 
2328                       attribute_names, attribute_values,
2329                       ctx, error))
2330         goto out;
2331       break;
2332
2333     case 'f':
2334       if (start_function (context, element_name, 
2335                           attribute_names, attribute_values,
2336                           ctx, error))
2337         goto out;
2338       else if (start_field (context, element_name, 
2339                             attribute_names, attribute_values,
2340                             ctx, error))
2341         goto out;
2342       break;
2343
2344     case 'g':
2345       if (start_glib_boxed (context, element_name,
2346                             attribute_names, attribute_values,
2347                             ctx, error))
2348         goto out;
2349       else if (start_glib_signal (context, element_name,
2350                              attribute_names, attribute_values,
2351                              ctx, error))
2352         goto out;
2353       break;
2354
2355     case 'i':
2356       if (strcmp (element_name, "include") == 0 &&
2357           ctx->state == STATE_REPOSITORY)
2358         {
2359           const gchar *name;
2360           const gchar *version;
2361
2362           name = find_attribute ("name", attribute_names, attribute_values);
2363           version = find_attribute ("version", attribute_names, attribute_values);
2364
2365           if (name == NULL)
2366             {
2367               MISSING_ATTRIBUTE (context, error, element_name, "name");
2368               break;
2369             }
2370           if (version == NULL)
2371             {
2372               MISSING_ATTRIBUTE (context, error, element_name, "version");
2373               break;
2374             }
2375
2376           if (!parse_include (context, ctx, name, version, error))
2377             break;
2378
2379           ctx->dependencies = g_list_prepend (ctx->dependencies,
2380                                               g_strdup_printf ("%s-%s", name, version));
2381
2382
2383           state_switch (ctx, STATE_INCLUDE);
2384           goto out;
2385         }
2386       if (start_interface (context, element_name, 
2387                            attribute_names, attribute_values,
2388                            ctx, error))
2389         goto out;
2390       else if (start_implements (context, element_name,
2391                                  attribute_names, attribute_values,
2392                                  ctx, error))
2393         goto out;
2394       break;
2395
2396     case 'm':
2397       if (start_function (context, element_name, 
2398                           attribute_names, attribute_values,
2399                           ctx, error))
2400         goto out;
2401       else if (start_member (context, element_name, 
2402                           attribute_names, attribute_values,
2403                           ctx, error))
2404         goto out;
2405       break;
2406
2407     case 'n':
2408       if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2409         {
2410           const gchar *name, *version, *shared_library;
2411           
2412           name = find_attribute ("name", attribute_names, attribute_values);
2413           version = find_attribute ("version", attribute_names, attribute_values);
2414           shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2415
2416           if (name == NULL)
2417             MISSING_ATTRIBUTE (context, error, element_name, "name");
2418           else if (version == NULL)
2419             MISSING_ATTRIBUTE (context, error, element_name, "version");
2420           else
2421             {
2422               ctx->current_module = g_ir_module_new (name, version, shared_library);
2423               ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2424               ctx->current_module->dependencies = ctx->dependencies;
2425               ctx->current_module->include_modules = g_list_copy (ctx->include_modules);
2426
2427               state_switch (ctx, STATE_NAMESPACE);
2428               goto out;
2429             }
2430         }
2431       break;
2432
2433     case 'p':
2434       if (start_property (context, element_name,
2435                           attribute_names, attribute_values,
2436                           ctx, error))
2437         goto out;
2438       else if (strcmp (element_name, "parameters") == 0 &&
2439                ctx->state == STATE_FUNCTION)
2440         {
2441           state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2442
2443           goto out;
2444         }
2445       else if (start_parameter (context, element_name,
2446                                 attribute_names, attribute_values,
2447                                 ctx, error))
2448         goto out;
2449
2450       break;
2451
2452     case 'r':
2453       if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
2454         {
2455           const gchar *version;
2456
2457           version = find_attribute ("version", attribute_names, attribute_values);
2458           
2459           if (version == NULL)
2460             MISSING_ATTRIBUTE (context, error, element_name, "version");
2461           else if (strcmp (version, "1.0") != 0)
2462             g_set_error (error,
2463                          G_MARKUP_ERROR,
2464                          G_MARKUP_ERROR_INVALID_CONTENT,
2465                          "Unsupported version '%s'",
2466                          version);
2467           else
2468             state_switch (ctx, STATE_REPOSITORY);
2469           
2470           goto out;
2471         }
2472       else if (start_return_value (context, element_name,
2473                                    attribute_names, attribute_values,
2474                                    ctx, error))
2475         goto out;      
2476       else if (strcmp (element_name, "requires") == 0 &&
2477                ctx->state == STATE_INTERFACE)
2478         {
2479           state_switch (ctx, STATE_REQUIRES);
2480           
2481           goto out;
2482         }
2483       else if (start_struct (context, element_name,
2484                              attribute_names, attribute_values,
2485                              ctx, error))
2486         goto out;      
2487       break;
2488
2489     case 'u':
2490       if (start_union (context, element_name,
2491                        attribute_names, attribute_values,
2492                        ctx, error))
2493         goto out;
2494       break;
2495
2496     case 't':
2497       if (start_type (context, element_name,
2498                       attribute_names, attribute_values,
2499                       ctx, error))
2500         goto out;
2501       break;
2502
2503     case 'v':
2504       if (start_vfunc (context, element_name,
2505                        attribute_names, attribute_values,
2506                        ctx, error))
2507         goto out;
2508       if (start_type (context, element_name,
2509                       attribute_names, attribute_values,
2510                       ctx, error))
2511         goto out;
2512       break;
2513     }
2514
2515   g_markup_parse_context_get_position (context, &line_number, &char_number);
2516
2517   if (error && *error == NULL)
2518     g_set_error (error,
2519                  G_MARKUP_ERROR,
2520                  G_MARKUP_ERROR_UNKNOWN_ELEMENT,
2521                  "Unexpected start tag '%s' on line %d char %d; current state=%d",
2522                  element_name,
2523                  line_number, char_number, ctx->state);
2524   
2525  out: ;
2526   if (*error) 
2527     {
2528       g_markup_parse_context_get_position (context, &line_number, &char_number);
2529
2530       fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message);
2531       backtrace_stderr ();
2532     }
2533 }
2534
2535 static gboolean
2536 require_one_of_end_elements (GMarkupParseContext *context,
2537                              ParseContext        *ctx,
2538                              const char          *actual_name,
2539                              GError             **error, 
2540                              ...)
2541 {
2542   va_list args;
2543   int line_number, char_number;
2544   const char *expected;
2545   gboolean matched = FALSE;
2546
2547   va_start (args, error);
2548
2549   while ((expected = va_arg (args, const char*)) != NULL) 
2550     {
2551       if (strcmp (expected, actual_name) == 0)
2552         {
2553           matched = TRUE;
2554           break;
2555         }
2556     }
2557
2558   va_end (args);
2559
2560   if (matched)
2561     return TRUE;
2562
2563   g_markup_parse_context_get_position (context, &line_number, &char_number);
2564   g_set_error (error,
2565                G_MARKUP_ERROR,
2566                G_MARKUP_ERROR_INVALID_CONTENT,
2567                "Unexpected end tag '%s' on line %d char %d; current state=%d",
2568                actual_name, 
2569                line_number, char_number, ctx->state);
2570   backtrace_stderr();
2571   return FALSE;
2572 }
2573
2574 static gboolean
2575 require_end_element (GMarkupParseContext *context,
2576                      ParseContext        *ctx,
2577                      const char          *expected_name,
2578                      const char          *actual_name,
2579                      GError             **error)
2580 {
2581   return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
2582 }
2583
2584 static void
2585 end_element_handler (GMarkupParseContext *context,
2586                      const gchar         *element_name,
2587                      gpointer             user_data,
2588                      GError             **error)
2589 {
2590   ParseContext *ctx = user_data;
2591
2592   g_debug ("</%s>", element_name);
2593
2594   switch (ctx->state)
2595     {
2596     case STATE_START:
2597     case STATE_END:
2598       /* no need to GError here, GMarkup already catches this */
2599       break;
2600
2601     case STATE_REPOSITORY:
2602       state_switch (ctx, STATE_END);
2603       break;
2604
2605     case STATE_INCLUDE:
2606       if (require_end_element (context, ctx, "include", element_name, error))
2607         {
2608           state_switch (ctx, STATE_REPOSITORY);
2609         }
2610       break;
2611
2612     case STATE_NAMESPACE:
2613       if (require_end_element (context, ctx, "namespace", element_name, error))
2614         {
2615           ctx->current_module = NULL;
2616           state_switch (ctx, STATE_REPOSITORY);
2617         }
2618       break;
2619
2620     case STATE_ALIAS:
2621       if (require_end_element (context, ctx, "alias", element_name, error))
2622         {
2623           state_switch (ctx, STATE_NAMESPACE);
2624         }
2625       break;
2626
2627     case STATE_FUNCTION_RETURN:
2628       if (strcmp ("type", element_name) == 0)
2629         break;
2630       if (require_end_element (context, ctx, "return-value", element_name, error))
2631         {
2632           state_switch (ctx, STATE_FUNCTION);
2633         }
2634       break;
2635
2636     case STATE_FUNCTION_PARAMETERS:
2637       if (require_end_element (context, ctx, "parameters", element_name, error))
2638         {
2639           state_switch (ctx, STATE_FUNCTION);
2640         }
2641       break;
2642
2643     case STATE_FUNCTION_PARAMETER:
2644       if (strcmp ("type", element_name) == 0)
2645         break;
2646       if (require_end_element (context, ctx, "parameter", element_name, error))
2647         {
2648           state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2649         }
2650       break;
2651
2652     case STATE_FUNCTION:
2653       {
2654         gboolean current_is_toplevel;
2655         GList *last = g_list_last (ctx->current_module->entries);
2656         
2657         current_is_toplevel = ctx->current_node == last->data;  
2658
2659         if (current_is_toplevel)
2660           {
2661             ctx->current_node = NULL;
2662             state_switch (ctx, STATE_NAMESPACE);
2663           }
2664         else 
2665           { 
2666             ctx->current_node = g_list_last (ctx->current_module->entries)->data;
2667             if (ctx->current_node->type == G_IR_NODE_INTERFACE)
2668               state_switch (ctx, STATE_INTERFACE);
2669             else if (ctx->current_node->type == G_IR_NODE_OBJECT) 
2670               state_switch (ctx, STATE_CLASS);
2671             else if (ctx->current_node->type == G_IR_NODE_BOXED)
2672               state_switch (ctx, STATE_BOXED);
2673             else if (ctx->current_node->type == G_IR_NODE_STRUCT)
2674               state_switch (ctx, STATE_STRUCT);
2675             else if (ctx->current_node->type == G_IR_NODE_UNION)
2676               state_switch (ctx, STATE_UNION);
2677             else
2678               {
2679                 int line_number, char_number;
2680                 g_markup_parse_context_get_position (context, &line_number, &char_number);
2681                 g_set_error (error,
2682                              G_MARKUP_ERROR,
2683                              G_MARKUP_ERROR_INVALID_CONTENT,
2684                              "Unexpected end tag '%s' on line %d char %d",
2685                              element_name,
2686                              line_number, char_number);
2687               }
2688           }
2689       }
2690       break;
2691
2692     case STATE_CLASS_FIELD:
2693       if (strcmp ("type", element_name) == 0)
2694         break;
2695       if (require_end_element (context, ctx, "field", element_name, error))
2696         {
2697           state_switch (ctx, STATE_CLASS);
2698         }
2699       break;
2700
2701     case STATE_CLASS_PROPERTY:
2702       if (strcmp ("type", element_name) == 0)
2703         break;
2704       if (require_end_element (context, ctx, "property", element_name, error))
2705         {
2706           state_switch (ctx, STATE_CLASS);
2707         }
2708       break;
2709
2710     case STATE_CLASS:
2711       if (require_end_element (context, ctx, "class", element_name, error))
2712         {
2713           ctx->current_node = NULL;
2714           state_switch (ctx, STATE_NAMESPACE);
2715         }
2716       break;
2717
2718     case STATE_ERRORDOMAIN:
2719       if (require_end_element (context, ctx, "errordomain", element_name, error))
2720         {
2721           ctx->current_node = NULL;
2722           state_switch (ctx, STATE_NAMESPACE);
2723         }
2724       break;
2725
2726     case STATE_INTERFACE_PROPERTY:
2727       if (strcmp ("type", element_name) == 0)
2728         break;
2729       if (require_end_element (context, ctx, "property", element_name, error))
2730         {
2731           state_switch (ctx, STATE_INTERFACE);
2732         }
2733       break;
2734
2735     case STATE_INTERFACE_FIELD:
2736       if (strcmp ("type", element_name) == 0)
2737         break;
2738       if (require_end_element (context, ctx, "field", element_name, error))
2739         {
2740           state_switch (ctx, STATE_INTERFACE);
2741         }
2742       break;
2743
2744     case STATE_INTERFACE:
2745       if (require_end_element (context, ctx, "interface", element_name, error))
2746         {
2747           ctx->current_node = NULL;
2748           state_switch (ctx, STATE_NAMESPACE);
2749         }
2750       break;
2751
2752     case STATE_ENUM:
2753       if (strcmp ("member", element_name) == 0)
2754         break;
2755       else if (require_one_of_end_elements (context, ctx, 
2756                                             element_name, error, "enumeration", 
2757                                             "bitfield", NULL))
2758         {
2759           ctx->current_node = NULL;
2760           state_switch (ctx, STATE_NAMESPACE);
2761         }
2762       break;
2763
2764     case STATE_BOXED:
2765       if (require_end_element (context, ctx, "glib:boxed", element_name, error))
2766         {
2767           ctx->current_node = NULL;
2768           state_switch (ctx, STATE_NAMESPACE);
2769         }
2770       break;
2771
2772     case STATE_BOXED_FIELD:
2773       if (strcmp ("type", element_name) == 0)
2774         break;
2775       if (require_end_element (context, ctx, "field", element_name, error))
2776         {
2777           state_switch (ctx, STATE_BOXED);
2778         }
2779       break;
2780
2781     case STATE_STRUCT_FIELD:
2782       if (strcmp ("type", element_name) == 0)
2783         break;
2784       if (require_end_element (context, ctx, "field", element_name, error))
2785         {
2786           state_switch (ctx, STATE_STRUCT);
2787         }
2788       break;
2789
2790     case STATE_STRUCT:
2791       if (require_end_element (context, ctx, "record", element_name, error))
2792         {
2793           ctx->current_node = NULL;
2794           state_switch (ctx, STATE_NAMESPACE);
2795         }
2796       break;
2797
2798     case STATE_UNION_FIELD:
2799       if (strcmp ("type", element_name) == 0)
2800         break;
2801       if (require_end_element (context, ctx, "field", element_name, error))
2802         {
2803           state_switch (ctx, STATE_UNION);
2804         }
2805       break;
2806
2807     case STATE_UNION:
2808       if (require_end_element (context, ctx, "union", element_name, error))
2809         {
2810           ctx->current_node = NULL;
2811           state_switch (ctx, STATE_NAMESPACE);
2812         }
2813       break;
2814     case STATE_IMPLEMENTS:
2815       if (strcmp ("interface", element_name) == 0)
2816         break;
2817       if (require_end_element (context, ctx, "implements", element_name, error))
2818         state_switch (ctx, STATE_CLASS);
2819       break;
2820     case STATE_REQUIRES:
2821       if (require_end_element (context, ctx, "requires", element_name, error))
2822         state_switch (ctx, STATE_INTERFACE);
2823       break;
2824     case STATE_NAMESPACE_CONSTANT:
2825     case STATE_CLASS_CONSTANT:
2826     case STATE_INTERFACE_CONSTANT:
2827       if (strcmp ("type", element_name) == 0)
2828         break;
2829       if (require_end_element (context, ctx, "constant", element_name, error))
2830         {
2831           ctx->current_node = NULL;
2832           switch (ctx->state)
2833             {
2834             case STATE_NAMESPACE_CONSTANT:
2835               state_switch (ctx, STATE_NAMESPACE);
2836               break;
2837             case STATE_CLASS_CONSTANT:
2838               state_switch (ctx, STATE_CLASS);
2839               break;
2840             case STATE_INTERFACE_CONSTANT:
2841               state_switch (ctx, STATE_INTERFACE);
2842               break;
2843             default:
2844               g_assert_not_reached ();
2845               break;
2846             }
2847         }
2848       break;
2849     case STATE_TYPE:
2850       if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
2851           (strcmp ("varargs", element_name) == 0))
2852         {
2853           end_type (ctx);
2854           break;
2855         }
2856     default:
2857       g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
2858     }
2859 }
2860
2861 static void 
2862 text_handler (GMarkupParseContext *context,
2863               const gchar         *text,
2864               gsize                text_len,  
2865               gpointer             user_data,
2866               GError             **error)
2867 {
2868   /* FIXME warn about non-whitespace text */
2869 }
2870
2871 static void
2872 cleanup (GMarkupParseContext *context,
2873          GError              *error,
2874          gpointer             user_data)
2875 {
2876   ParseContext *ctx = user_data;
2877   GList *m;
2878
2879   for (m = ctx->modules; m; m = m->next)
2880     g_ir_module_free (m->data);
2881   g_list_free (ctx->modules);
2882   ctx->modules = NULL;
2883   
2884   ctx->current_module = NULL;
2885 }
2886
2887 static GList *
2888 post_filter_varargs_functions (GList *list)
2889 {
2890   GList *iter;
2891
2892   iter = list;
2893   while (iter)
2894     {
2895       GList *link = iter;
2896       GIrNode *node = iter->data;
2897
2898       iter = iter->next;
2899
2900       if (node->type == G_IR_NODE_FUNCTION)
2901         {
2902           if (((GIrNodeFunction*)node)->is_varargs)
2903             {
2904               list = g_list_delete_link (list, link);
2905             }
2906         }
2907     }
2908   return list;
2909 }
2910
2911 static void
2912 post_filter (GIrModule *module)
2913 {
2914   GList *iter;
2915
2916   module->entries = post_filter_varargs_functions (module->entries);
2917   iter = module->entries;
2918   while (iter)
2919     {
2920       GIrNode *node = iter->data;
2921
2922       iter = iter->next;
2923       
2924       if (node->type == G_IR_NODE_OBJECT || 
2925           node->type == G_IR_NODE_INTERFACE) 
2926         {
2927           GIrNodeInterface *iface = (GIrNodeInterface*)node;
2928           iface->members = post_filter_varargs_functions (iface->members);
2929         }
2930       else if (node->type == G_IR_NODE_BOXED)
2931         {
2932           GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
2933           boxed->members = post_filter_varargs_functions (boxed->members);
2934         }
2935       else if (node->type == G_IR_NODE_STRUCT)
2936         {
2937           GIrNodeStruct *iface = (GIrNodeStruct*)node;
2938           iface->members = post_filter_varargs_functions (iface->members);
2939         }
2940       else if (node->type == G_IR_NODE_UNION)
2941         {
2942           GIrNodeUnion *iface = (GIrNodeUnion*)node;
2943           iface->members = post_filter_varargs_functions (iface->members);
2944         }
2945     }
2946 }
2947
2948 GList * 
2949 g_ir_parse_string (const gchar  *namespace,
2950                    const gchar *const *includes,
2951                    const gchar  *buffer, 
2952                    gssize        length,
2953                    GError      **error)
2954 {
2955   ParseContext ctx = { 0 };
2956   GMarkupParseContext *context;
2957
2958   ctx.state = STATE_START;
2959   ctx.includes = includes;
2960   ctx.prefix_aliases = FALSE;
2961   ctx.namespace = namespace;
2962   ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
2963   ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
2964   ctx.type_depth = 0;
2965   ctx.dependencies = NULL;
2966   ctx.current_module = NULL;
2967
2968   context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
2969
2970   if (!g_markup_parse_context_parse (context, buffer, length, error))
2971     goto out;
2972
2973   if (!g_markup_parse_context_end_parse (context, error))
2974     goto out;
2975
2976   g_markup_parse_context_free (context);
2977   
2978   context = g_markup_parse_context_new (&parser, 0, &ctx, NULL);
2979   if (!g_markup_parse_context_parse (context, buffer, length, error))
2980     goto out;
2981
2982   if (!g_markup_parse_context_end_parse (context, error))
2983     goto out;
2984
2985  out:
2986
2987   g_hash_table_destroy (ctx.aliases);
2988   g_hash_table_destroy (ctx.disguised_structures);
2989   
2990   g_markup_parse_context_free (context);
2991   
2992   return ctx.modules;
2993 }
2994
2995 GList *
2996 g_ir_parse_file (const gchar  *filename,
2997                  const gchar *const *includes,
2998                  GError      **error)
2999 {
3000   gchar *buffer;
3001   gsize length;
3002   GList *modules;
3003   GList *iter;
3004   const char *slash;
3005   char *namespace;
3006
3007   if (!g_str_has_suffix (filename, ".gir"))
3008     {
3009       g_set_error (error,
3010                    G_MARKUP_ERROR,
3011                    G_MARKUP_ERROR_INVALID_CONTENT,
3012                    "Expected filename to end with '.gir'");
3013       return NULL;
3014     }
3015
3016   g_debug ("[parsing] filename %s", filename);
3017
3018   slash = g_strrstr (filename, "/");
3019   if (!slash)
3020     namespace = g_strdup (filename);
3021   else
3022     namespace = g_strdup (slash+1);
3023   namespace[strlen(namespace)-4] = '\0';
3024
3025   if (!g_file_get_contents (filename, &buffer, &length, error))
3026     return NULL;
3027   
3028   modules = g_ir_parse_string (namespace, includes, buffer, length, error);
3029
3030   for (iter = modules; iter; iter = iter->next) 
3031     {
3032       post_filter ((GIrModule*)iter->data);
3033     }
3034
3035   g_free (namespace);
3036
3037   g_free (buffer);
3038
3039   return modules;
3040 }
3041
3042