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