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