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