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