1 /* GObject introspection: A parser for the XML GIR format
3 * Copyright (C) 2008 Philip Van Hoof
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
26 #include "girparser.h"
27 #include "girmodule.h"
41 STATE_FUNCTION_RETURN,
42 STATE_FUNCTION_PARAMETERS,
43 STATE_FUNCTION_PARAMETER, /* 10 */
48 STATE_INTERFACE_PROPERTY, /* 15 */
49 STATE_INTERFACE_FIELD,
53 STATE_BOXED_FIELD, /* 20 */
58 STATE_UNION_FIELD, /* 25 */
59 STATE_NAMESPACE_CONSTANT,
61 STATE_INTERFACE_CONSTANT,
66 typedef struct _ParseContext ParseContext;
70 ParseState prev_state;
72 const char * const*includes;
75 GList *include_modules;
76 gboolean prefix_aliases;
79 GHashTable *disguised_structures;
81 const char *namespace;
82 GIrModule *current_module;
83 GIrNode *current_node;
84 GIrNode *current_typed;
87 GList *type_parameters;
91 static void start_element_handler (GMarkupParseContext *context,
92 const gchar *element_name,
93 const gchar **attribute_names,
94 const gchar **attribute_values,
97 static void end_element_handler (GMarkupParseContext *context,
98 const gchar *element_name,
101 static void text_handler (GMarkupParseContext *context,
106 static void cleanup (GMarkupParseContext *context,
110 static GMarkupParser parser =
112 start_element_handler,
120 start_alias (GMarkupParseContext *context,
121 const gchar *element_name,
122 const gchar **attribute_names,
123 const gchar **attribute_values,
127 static const gchar *find_attribute (const gchar *name,
128 const gchar **attribute_names,
129 const gchar **attribute_values);
132 firstpass_start_element_handler (GMarkupParseContext *context,
133 const gchar *element_name,
134 const gchar **attribute_names,
135 const gchar **attribute_values,
139 ParseContext *ctx = user_data;
141 if (strcmp (element_name, "alias") == 0)
143 start_alias (context, element_name, attribute_names, attribute_values,
146 else if (strcmp (element_name, "record") == 0)
149 const gchar *disguised;
151 name = find_attribute ("name", attribute_names, attribute_values);
152 disguised = find_attribute ("disguised", attribute_names, attribute_values);
154 if (disguised && strcmp (disguised, "1") == 0)
158 if (ctx->prefix_aliases)
160 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
164 key = g_strdup (name);
167 g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
173 firstpass_end_element_handler (GMarkupParseContext *context,
174 const gchar *element_name,
180 static GMarkupParser firstpass_parser =
182 firstpass_start_element_handler,
183 firstpass_end_element_handler,
190 locate_gir (const char *name, const char *version, const char * const* extra_paths)
192 const gchar *const *datadirs;
193 const gchar *const *dir;
197 datadirs = g_get_system_data_dirs ();
199 girname = g_strdup_printf ("%s-%s.gir", name, version);
201 if (extra_paths != NULL)
203 for (dir = extra_paths; *dir; dir++)
205 path = g_build_filename (*dir, girname, NULL);
206 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
212 for (dir = datadirs; *dir; dir++)
214 path = g_build_filename (*dir, "gir", girname, NULL);
215 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
224 #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \
226 int line_number, char_number; \
227 g_markup_parse_context_get_position (context, &line_number, &char_number); \
228 g_set_error (error, \
230 G_MARKUP_ERROR_INVALID_CONTENT, \
231 "Line %d, character %d: The attribute '%s' on the element '%s' must be specified", \
232 line_number, char_number, attribute, element); \
236 backtrace_stderr (void)
238 #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
244 size = backtrace (array, 50);
245 strings = (char**) backtrace_symbols (array, size);
247 fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size);
249 for (i = 0; i < size; i++)
250 fprintf (stderr, "%s\n", strings[i]);
252 fprintf (stderr, "--- END BACKTRACE ---\n", size);
260 find_attribute (const gchar *name,
261 const gchar **attribute_names,
262 const gchar **attribute_values)
266 for (i = 0; attribute_names[i] != NULL; i++)
267 if (strcmp (attribute_names[i], name) == 0)
268 return attribute_values[i];
274 state_switch (ParseContext *ctx, ParseState newstate)
276 g_debug ("State: %d", newstate);
277 ctx->prev_state = ctx->state;
278 ctx->state = newstate;
281 static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
282 gboolean in_gobject);
290 static BasicTypeInfo basic_types[] = {
291 { "none", GI_TYPE_TAG_VOID, 0 },
292 { "any", GI_TYPE_TAG_VOID, 1 },
294 { "bool", GI_TYPE_TAG_BOOLEAN, 0 },
295 { "char", GI_TYPE_TAG_INT8, 0 },
296 { "int8", GI_TYPE_TAG_INT8, 0 },
297 { "uint8", GI_TYPE_TAG_UINT8, 0 },
298 { "int16", GI_TYPE_TAG_INT16, 0 },
299 { "uint16", GI_TYPE_TAG_UINT16, 0 },
300 { "int32", GI_TYPE_TAG_INT32, 0 },
301 { "uint32", GI_TYPE_TAG_UINT32, 0 },
302 { "int64", GI_TYPE_TAG_INT64, 0 },
303 { "uint64", GI_TYPE_TAG_UINT64, 0 },
304 { "int", GI_TYPE_TAG_INT, 0 },
305 { "uint", GI_TYPE_TAG_UINT, 0 },
306 { "long", GI_TYPE_TAG_LONG, 0 },
307 { "ulong", GI_TYPE_TAG_ULONG, 0 },
308 { "ssize_t", GI_TYPE_TAG_SSIZE, 0 },
309 { "ssize", GI_TYPE_TAG_SSIZE, 0 },
310 { "size_t", GI_TYPE_TAG_SIZE, 0 },
311 { "size", GI_TYPE_TAG_SIZE, 0 },
312 { "float", GI_TYPE_TAG_FLOAT, 0 },
313 { "double", GI_TYPE_TAG_DOUBLE, 0 },
314 { "time_t", GI_TYPE_TAG_TIME_T, 0 },
315 { "GType", GI_TYPE_TAG_GTYPE, 0 },
316 { "utf8", GI_TYPE_TAG_UTF8, 1 },
317 { "filename", GI_TYPE_TAG_FILENAME,1 },
320 static const BasicTypeInfo *
321 parse_basic (const char *str)
324 gint n_basic = G_N_ELEMENTS (basic_types);
326 for (i = 0; i < n_basic; i++)
328 if (g_str_has_prefix (str, basic_types[i].str))
329 return &(basic_types[i]);
335 parse_type_internal (const gchar *str, char **next, gboolean in_glib,
338 const BasicTypeInfo *basic;
340 char *temporary_type = NULL;
342 type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
344 type->unparsed = g_strdup (str);
346 /* See comment below on GLib.List handling */
347 if (in_gobject && strcmp (str, "Type") == 0)
349 temporary_type = g_strdup ("GLib.Type");
350 str = temporary_type;
353 basic = parse_basic (str);
356 type->is_basic = TRUE;
357 type->tag = basic->tag;
358 type->is_pointer = basic->pointer;
360 str += strlen(basic->str);
364 /* If we're inside GLib, handle "List" etc. by prefixing with
365 * "GLib." so the parsing code below doesn't have to get more
368 if (g_str_has_prefix (str, "List<") ||
369 strcmp (str, "List") == 0)
371 temporary_type = g_strdup_printf ("GLib.List%s", str + 4);
372 str = temporary_type;
374 else if (g_str_has_prefix (str, "SList<") ||
375 strcmp (str, "SList") == 0)
377 temporary_type = g_strdup_printf ("GLib.SList%s", str + 5);
378 str = temporary_type;
380 else if (g_str_has_prefix (str, "HashTable<") ||
381 strcmp (str, "HashTable") == 0)
383 temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9);
384 str = temporary_type;
386 else if (g_str_has_prefix (str, "Error<") ||
387 strcmp (str, "Error") == 0)
389 temporary_type = g_strdup_printf ("GLib.Error%s", str + 5);
390 str = temporary_type;
395 /* found a basic type */;
396 else if (g_str_has_prefix (str, "GLib.List") ||
397 g_str_has_prefix (str, "GLib.SList"))
399 str += strlen ("GLib.");
400 if (g_str_has_prefix (str, "List"))
402 type->tag = GI_TYPE_TAG_GLIST;
403 type->is_glist = TRUE;
404 type->is_pointer = TRUE;
405 str += strlen ("List");
409 type->tag = GI_TYPE_TAG_GSLIST;
410 type->is_gslist = TRUE;
411 type->is_pointer = TRUE;
412 str += strlen ("SList");
415 else if (g_str_has_prefix (str, "GLib.HashTable"))
417 str += strlen ("GLib.");
419 type->tag = GI_TYPE_TAG_GHASH;
420 type->is_ghashtable = TRUE;
421 type->is_pointer = TRUE;
422 str += strlen ("HashTable");
424 else if (g_str_has_prefix (str, "GLib.Error"))
426 str += strlen ("GLib.");
428 type->tag = GI_TYPE_TAG_ERROR;
429 type->is_error = TRUE;
430 type->is_pointer = TRUE;
431 str += strlen ("Error");
438 end = strchr (str, '>');
439 tmp = g_strndup (str, end - str);
440 type->errors = g_strsplit (tmp, ",", 0);
448 type->tag = GI_TYPE_TAG_INTERFACE;
449 type->is_interface = TRUE;
450 const char *start = str;
452 /* must be an interface type */
453 while (g_ascii_isalnum (*str) ||
460 type->interface = g_strndup (start, str - start);
465 g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR);
466 g_free (temporary_type);
470 g_ir_node_free ((GIrNode *)type);
471 g_free (temporary_type);
476 resolve_aliases (ParseContext *ctx, const gchar *type)
480 GSList *seen_values = NULL;
484 /* If we are in an included module, then we need to qualify the
485 * names of types before resolving them, since they will have
486 * been stored in the aliases qualified.
488 if (ctx->prefix_aliases && strchr (type, '.') == NULL)
490 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
496 seen_values = g_slist_prepend (seen_values, (char*)lookup);
497 while (g_hash_table_lookup_extended (ctx->aliases, lookup, &orig, &value))
499 g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
501 if (g_slist_find_custom (seen_values, lookup,
502 (GCompareFunc)strcmp) != NULL)
504 seen_values = g_slist_prepend (seen_values, (gchar*)lookup);
506 g_slist_free (seen_values);
508 if (lookup == prefixed)
517 parse_type (ParseContext *ctx, const gchar *type)
520 const BasicTypeInfo *basic;
521 gboolean in_glib, in_gobject;
523 in_glib = strcmp (ctx->namespace, "GLib") == 0;
524 in_gobject = strcmp (ctx->namespace, "GObject") == 0;
526 /* Do not search aliases for basic types */
527 basic = parse_basic (type);
529 type = resolve_aliases (ctx, type);
531 node = parse_type_internal (type, NULL, in_glib, in_gobject);
533 g_debug ("Parsed type: %s => %d", type, node->tag);
535 g_critical ("Failed to parse type: '%s'", type);
541 start_glib_boxed (GMarkupParseContext *context,
542 const gchar *element_name,
543 const gchar **attribute_names,
544 const gchar **attribute_values,
549 const gchar *typename;
550 const gchar *typeinit;
551 const gchar *deprecated;
554 if (!(strcmp (element_name, "glib:boxed") == 0 &&
555 ctx->state == STATE_NAMESPACE))
558 name = find_attribute ("glib:name", attribute_names, attribute_values);
559 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
560 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
561 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
565 MISSING_ATTRIBUTE (context, error, element_name, "glib:name");
568 else if (typename == NULL)
570 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
573 else if (typeinit == NULL)
575 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
579 boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED);
581 ((GIrNode *)boxed)->name = g_strdup (name);
582 boxed->gtype_name = g_strdup (typename);
583 boxed->gtype_init = g_strdup (typeinit);
585 boxed->deprecated = TRUE;
587 boxed->deprecated = FALSE;
589 ctx->current_node = (GIrNode *)boxed;
590 ctx->current_module->entries =
591 g_list_append (ctx->current_module->entries, boxed);
593 state_switch (ctx, STATE_BOXED);
599 start_function (GMarkupParseContext *context,
600 const gchar *element_name,
601 const gchar **attribute_names,
602 const gchar **attribute_values,
608 const gchar *deprecated;
610 GIrNodeFunction *function;
611 gboolean found = FALSE;
615 case STATE_NAMESPACE:
616 found = (strcmp (element_name, "function") == 0 ||
617 strcmp (element_name, "callback") == 0);
623 found = strcmp (element_name, "constructor") == 0;
625 case STATE_INTERFACE:
627 strcmp (element_name, "method") == 0 ||
628 strcmp (element_name, "callback") == 0);
637 name = find_attribute ("name", attribute_names, attribute_values);
638 symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
639 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
640 throws = find_attribute ("throws", attribute_names, attribute_values);
644 MISSING_ATTRIBUTE (context, error, element_name, "name");
647 else if (strcmp (element_name, "callback") != 0 && symbol == NULL)
649 MISSING_ATTRIBUTE (context, error, element_name, "c:identifier");
653 function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION);
655 ((GIrNode *)function)->name = g_strdup (name);
656 function->symbol = g_strdup (symbol);
657 function->parameters = NULL;
659 function->deprecated = TRUE;
661 function->deprecated = FALSE;
663 if (strcmp (element_name, "method") == 0 ||
664 strcmp (element_name, "constructor") == 0)
666 function->is_method = TRUE;
668 if (strcmp (element_name, "constructor") == 0)
669 function->is_constructor = TRUE;
671 function->is_constructor = FALSE;
675 function->is_method = FALSE;
676 function->is_setter = FALSE;
677 function->is_getter = FALSE;
678 function->is_constructor = FALSE;
679 if (strcmp (element_name, "callback") == 0)
680 ((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
683 if (throws && strcmp (throws, "1") == 0)
684 function->throws = TRUE;
686 function->throws = FALSE;
688 if (ctx->current_node == NULL)
690 ctx->current_module->entries =
691 g_list_append (ctx->current_module->entries, function);
694 switch (ctx->current_node->type)
696 case G_IR_NODE_INTERFACE:
697 case G_IR_NODE_OBJECT:
699 GIrNodeInterface *iface;
701 iface = (GIrNodeInterface *)ctx->current_node;
702 iface->members = g_list_append (iface->members, function);
705 case G_IR_NODE_BOXED:
709 boxed = (GIrNodeBoxed *)ctx->current_node;
710 boxed->members = g_list_append (boxed->members, function);
713 case G_IR_NODE_STRUCT:
715 GIrNodeStruct *struct_;
717 struct_ = (GIrNodeStruct *)ctx->current_node;
718 struct_->members = g_list_append (struct_->members, function); }
720 case G_IR_NODE_UNION:
722 GIrNodeUnion *union_;
724 union_ = (GIrNodeUnion *)ctx->current_node;
725 union_->members = g_list_append (union_->members, function);
729 g_assert_not_reached ();
732 ctx->current_node = (GIrNode *)function;
733 state_switch (ctx, STATE_FUNCTION);
739 parse_param_transfer (GIrNodeParam *param, const gchar *transfer)
741 if (transfer == NULL)
743 g_warning ("required attribute 'transfer-ownership' missing");
745 else if (strcmp (transfer, "none") == 0)
747 param->transfer = FALSE;
748 param->shallow_transfer = FALSE;
750 else if (strcmp (transfer, "container") == 0)
752 param->transfer = FALSE;
753 param->shallow_transfer = TRUE;
755 else if (strcmp (transfer, "full") == 0)
757 param->transfer = TRUE;
758 param->shallow_transfer = FALSE;
762 g_warning ("Unknown transfer-ownership value: %s", transfer);
767 start_parameter (GMarkupParseContext *context,
768 const gchar *element_name,
769 const gchar **attribute_names,
770 const gchar **attribute_values,
775 const gchar *direction;
778 const gchar *optional;
779 const gchar *allow_none;
780 const gchar *transfer;
783 if (!(strcmp (element_name, "parameter") == 0 &&
784 ctx->state == STATE_FUNCTION_PARAMETERS))
787 name = find_attribute ("name", attribute_names, attribute_values);
788 direction = find_attribute ("direction", attribute_names, attribute_values);
789 retval = find_attribute ("retval", attribute_names, attribute_values);
790 dipper = find_attribute ("dipper", attribute_names, attribute_values);
791 optional = find_attribute ("optional", attribute_names, attribute_values);
792 allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
793 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
798 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
800 ctx->current_typed = (GIrNode*) param;
801 ctx->current_typed->name = g_strdup (name);
803 state_switch (ctx, STATE_FUNCTION_PARAMETER);
805 if (direction && strcmp (direction, "out") == 0)
810 else if (direction && strcmp (direction, "inout") == 0)
821 if (retval && strcmp (retval, "1") == 0)
822 param->retval = TRUE;
824 param->retval = FALSE;
826 if (dipper && strcmp (dipper, "1") == 0)
827 param->dipper = TRUE;
829 param->dipper = FALSE;
831 if (optional && strcmp (optional, "1") == 0)
832 param->optional = TRUE;
834 param->optional = FALSE;
836 if (allow_none && strcmp (allow_none, "1") == 0)
837 param->allow_none = TRUE;
839 param->allow_none = FALSE;
841 parse_param_transfer (param, transfer);
843 ((GIrNode *)param)->name = g_strdup (name);
845 switch (ctx->current_node->type)
847 case G_IR_NODE_FUNCTION:
848 case G_IR_NODE_CALLBACK:
850 GIrNodeFunction *func;
852 func = (GIrNodeFunction *)ctx->current_node;
853 func->parameters = g_list_append (func->parameters, param);
856 case G_IR_NODE_SIGNAL:
858 GIrNodeSignal *signal;
860 signal = (GIrNodeSignal *)ctx->current_node;
861 signal->parameters = g_list_append (signal->parameters, param);
864 case G_IR_NODE_VFUNC:
868 vfunc = (GIrNodeVFunc *)ctx->current_node;
869 vfunc->parameters = g_list_append (vfunc->parameters, param);
873 g_assert_not_reached ();
880 start_field (GMarkupParseContext *context,
881 const gchar *element_name,
882 const gchar **attribute_names,
883 const gchar **attribute_values,
888 const gchar *readable;
889 const gchar *writable;
900 case STATE_INTERFACE:
906 if (strcmp (element_name, "field") != 0)
909 name = find_attribute ("name", attribute_names, attribute_values);
910 readable = find_attribute ("readable", attribute_names, attribute_values);
911 writable = find_attribute ("writable", attribute_names, attribute_values);
912 bits = find_attribute ("bits", attribute_names, attribute_values);
913 branch = find_attribute ("branch", attribute_names, attribute_values);
917 MISSING_ATTRIBUTE (context, error, element_name, "name");
921 field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD);
922 ctx->current_typed = (GIrNode*) field;
923 ((GIrNode *)field)->name = g_strdup (name);
924 /* Fields are assumed to be read-only.
925 * (see also girwriter.py and generate.c)
927 field->readable = readable == NULL || strcmp (readable, "0") == 0;
928 field->writable = writable != NULL && strcmp (writable, "1") == 0;
931 field->bits = atoi (bits);
935 switch (ctx->current_node->type)
937 case G_IR_NODE_OBJECT:
939 GIrNodeInterface *iface;
941 iface = (GIrNodeInterface *)ctx->current_node;
942 iface->members = g_list_append (iface->members, field);
943 state_switch (ctx, STATE_CLASS_FIELD);
946 case G_IR_NODE_INTERFACE:
948 GIrNodeInterface *iface;
950 iface = (GIrNodeInterface *)ctx->current_node;
951 iface->members = g_list_append (iface->members, field);
952 state_switch (ctx, STATE_INTERFACE_FIELD);
955 case G_IR_NODE_BOXED:
959 boxed = (GIrNodeBoxed *)ctx->current_node;
960 boxed->members = g_list_append (boxed->members, field);
961 state_switch (ctx, STATE_BOXED_FIELD);
964 case G_IR_NODE_STRUCT:
966 GIrNodeStruct *struct_;
968 struct_ = (GIrNodeStruct *)ctx->current_node;
969 struct_->members = g_list_append (struct_->members, field);
970 state_switch (ctx, STATE_STRUCT_FIELD);
973 case G_IR_NODE_UNION:
975 GIrNodeUnion *union_;
977 union_ = (GIrNodeUnion *)ctx->current_node;
978 union_->members = g_list_append (union_->members, field);
981 GIrNodeConstant *constant;
983 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
984 ((GIrNode *)constant)->name = g_strdup (name);
985 constant->value = g_strdup (branch);
986 constant->type = union_->discriminator_type;
987 constant->deprecated = FALSE;
989 union_->discriminators = g_list_append (union_->discriminators, constant);
991 state_switch (ctx, STATE_UNION_FIELD);
995 g_assert_not_reached ();
1002 start_alias (GMarkupParseContext *context,
1003 const gchar *element_name,
1004 const gchar **attribute_names,
1005 const gchar **attribute_values,
1010 const gchar *target;
1014 name = find_attribute ("name", attribute_names, attribute_values);
1017 MISSING_ATTRIBUTE (context, error, element_name, "name");
1021 target = find_attribute ("target", attribute_names, attribute_values);
1024 MISSING_ATTRIBUTE (context, error, element_name, "target");
1028 value = g_strdup (target);
1029 if (ctx->prefix_aliases)
1031 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
1032 if (!strchr (target, '.'))
1034 const BasicTypeInfo *basic = parse_basic (target);
1038 /* For non-basic types, re-qualify the interface */
1039 value = g_strdup_printf ("%s.%s", ctx->namespace, target);
1045 key = g_strdup (name);
1047 g_hash_table_insert (ctx->aliases, key, value);
1053 start_enum (GMarkupParseContext *context,
1054 const gchar *element_name,
1055 const gchar **attribute_names,
1056 const gchar **attribute_values,
1060 if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
1061 (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))
1064 const gchar *typename;
1065 const gchar *typeinit;
1066 const gchar *deprecated;
1068 name = find_attribute ("name", attribute_names, attribute_values);
1069 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1070 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1071 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1074 MISSING_ATTRIBUTE (context, error, element_name, "name");
1079 if (strcmp (element_name, "enumeration") == 0)
1080 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM);
1082 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS);
1083 ((GIrNode *)enum_)->name = g_strdup (name);
1084 enum_->gtype_name = g_strdup (typename);
1085 enum_->gtype_init = g_strdup (typeinit);
1087 enum_->deprecated = TRUE;
1089 enum_->deprecated = FALSE;
1091 ctx->current_node = (GIrNode *) enum_;
1092 ctx->current_module->entries =
1093 g_list_append (ctx->current_module->entries, enum_);
1095 state_switch (ctx, STATE_ENUM);
1104 start_property (GMarkupParseContext *context,
1105 const gchar *element_name,
1106 const gchar **attribute_names,
1107 const gchar **attribute_values,
1111 if (strcmp (element_name, "property") == 0 &&
1112 (ctx->state == STATE_CLASS ||
1113 ctx->state == STATE_INTERFACE))
1116 const gchar *readable;
1117 const gchar *writable;
1118 const gchar *construct;
1119 const gchar *construct_only;
1121 name = find_attribute ("name", attribute_names, attribute_values);
1122 readable = find_attribute ("readable", attribute_names, attribute_values);
1123 writable = find_attribute ("writable", attribute_names, attribute_values);
1124 construct = find_attribute ("construct", attribute_names, attribute_values);
1125 construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
1128 MISSING_ATTRIBUTE (context, error, element_name, "name");
1131 GIrNodeProperty *property;
1132 GIrNodeInterface *iface;
1134 property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
1135 ctx->current_typed = (GIrNode*) property;
1137 ((GIrNode *)property)->name = g_strdup (name);
1139 /* Assume properties are readable */
1140 if (readable == NULL || strcmp (readable, "1") == 0)
1141 property->readable = TRUE;
1143 property->readable = FALSE;
1144 if (writable && strcmp (writable, "1") == 0)
1145 property->writable = TRUE;
1147 property->writable = FALSE;
1148 if (construct && strcmp (construct, "1") == 0)
1149 property->construct = TRUE;
1151 property->construct = FALSE;
1152 if (construct_only && strcmp (construct_only, "1") == 0)
1153 property->construct_only = TRUE;
1155 property->construct_only = FALSE;
1157 iface = (GIrNodeInterface *)ctx->current_node;
1158 iface->members = g_list_append (iface->members, property);
1160 if (ctx->state == STATE_CLASS)
1161 state_switch (ctx, STATE_CLASS_PROPERTY);
1162 else if (ctx->state == STATE_INTERFACE)
1163 state_switch (ctx, STATE_INTERFACE_PROPERTY);
1165 g_assert_not_reached ();
1174 parse_value (const gchar *str)
1178 /* FIXME just a quick hack */
1179 shift_op = strstr (str, "<<");
1185 base = strtol (str, NULL, 10);
1186 shift = strtol (shift_op + 3, NULL, 10);
1188 return base << shift;
1191 return strtol (str, NULL, 10);
1197 start_member (GMarkupParseContext *context,
1198 const gchar *element_name,
1199 const gchar **attribute_names,
1200 const gchar **attribute_values,
1204 if (strcmp (element_name, "member") == 0 &&
1205 ctx->state == STATE_ENUM)
1209 const gchar *deprecated;
1211 name = find_attribute ("name", attribute_names, attribute_values);
1212 value = find_attribute ("value", attribute_names, attribute_values);
1213 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1216 MISSING_ATTRIBUTE (context, error, element_name, "name");
1220 GIrNodeValue *value_;
1222 value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
1224 ((GIrNode *)value_)->name = g_strdup (name);
1226 value_->value = parse_value (value);
1229 value_->deprecated = TRUE;
1231 value_->deprecated = FALSE;
1233 enum_ = (GIrNodeEnum *)ctx->current_node;
1234 enum_->values = g_list_append (enum_->values, value_);
1243 start_constant (GMarkupParseContext *context,
1244 const gchar *element_name,
1245 const gchar **attribute_names,
1246 const gchar **attribute_values,
1250 if (strcmp (element_name, "constant") == 0 &&
1251 (ctx->state == STATE_NAMESPACE ||
1252 ctx->state == STATE_CLASS ||
1253 ctx->state == STATE_INTERFACE))
1257 const gchar *deprecated;
1259 name = find_attribute ("name", attribute_names, attribute_values);
1260 value = find_attribute ("value", attribute_names, attribute_values);
1261 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1264 MISSING_ATTRIBUTE (context, error, element_name, "name");
1265 else if (value == NULL)
1266 MISSING_ATTRIBUTE (context, error, element_name, "value");
1269 GIrNodeConstant *constant;
1271 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1273 ((GIrNode *)constant)->name = g_strdup (name);
1274 constant->value = g_strdup (value);
1276 ctx->current_typed = (GIrNode*) constant;
1279 constant->deprecated = TRUE;
1281 constant->deprecated = FALSE;
1283 if (ctx->state == STATE_NAMESPACE)
1285 ctx->current_node = (GIrNode *) constant;
1286 ctx->current_module->entries =
1287 g_list_append (ctx->current_module->entries, constant);
1291 GIrNodeInterface *iface;
1293 iface = (GIrNodeInterface *)ctx->current_node;
1294 iface->members = g_list_append (iface->members, constant);
1299 case STATE_NAMESPACE:
1300 state_switch (ctx, STATE_NAMESPACE_CONSTANT);
1303 state_switch (ctx, STATE_CLASS_CONSTANT);
1305 case STATE_INTERFACE:
1306 state_switch (ctx, STATE_INTERFACE_CONSTANT);
1309 g_assert_not_reached ();
1320 start_errordomain (GMarkupParseContext *context,
1321 const gchar *element_name,
1322 const gchar **attribute_names,
1323 const gchar **attribute_values,
1327 if (strcmp (element_name, "errordomain") == 0 &&
1328 ctx->state == STATE_NAMESPACE)
1331 const gchar *getquark;
1333 const gchar *deprecated;
1335 name = find_attribute ("name", attribute_names, attribute_values);
1336 getquark = find_attribute ("get-quark", attribute_names, attribute_values);
1337 codes = find_attribute ("codes", attribute_names, attribute_values);
1338 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1341 MISSING_ATTRIBUTE (context, error, element_name, "name");
1342 else if (getquark == NULL)
1343 MISSING_ATTRIBUTE (context, error, element_name, "getquark");
1344 else if (codes == NULL)
1345 MISSING_ATTRIBUTE (context, error, element_name, "codes");
1348 GIrNodeErrorDomain *domain;
1350 domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
1352 ((GIrNode *)domain)->name = g_strdup (name);
1353 domain->getquark = g_strdup (getquark);
1354 domain->codes = g_strdup (codes);
1357 domain->deprecated = TRUE;
1359 domain->deprecated = FALSE;
1361 ctx->current_node = (GIrNode *) domain;
1362 ctx->current_module->entries =
1363 g_list_append (ctx->current_module->entries, domain);
1365 state_switch (ctx, STATE_ERRORDOMAIN);
1374 start_interface (GMarkupParseContext *context,
1375 const gchar *element_name,
1376 const gchar **attribute_names,
1377 const gchar **attribute_values,
1381 if (strcmp (element_name, "interface") == 0 &&
1382 ctx->state == STATE_NAMESPACE)
1385 const gchar *typename;
1386 const gchar *typeinit;
1387 const gchar *deprecated;
1389 name = find_attribute ("name", attribute_names, attribute_values);
1390 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1391 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1392 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1395 MISSING_ATTRIBUTE (context, error, element_name, "name");
1396 else if (typename == NULL)
1397 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1398 else if (typeinit == NULL)
1399 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1402 GIrNodeInterface *iface;
1404 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE);
1405 ((GIrNode *)iface)->name = g_strdup (name);
1406 iface->gtype_name = g_strdup (typename);
1407 iface->gtype_init = g_strdup (typeinit);
1409 iface->deprecated = TRUE;
1411 iface->deprecated = FALSE;
1413 ctx->current_node = (GIrNode *) iface;
1414 ctx->current_module->entries =
1415 g_list_append (ctx->current_module->entries, iface);
1417 state_switch (ctx, STATE_INTERFACE);
1427 start_class (GMarkupParseContext *context,
1428 const gchar *element_name,
1429 const gchar **attribute_names,
1430 const gchar **attribute_values,
1434 if (strcmp (element_name, "class") == 0 &&
1435 ctx->state == STATE_NAMESPACE)
1438 const gchar *parent;
1439 const gchar *typename;
1440 const gchar *typeinit;
1441 const gchar *deprecated;
1442 const gchar *abstract;
1444 name = find_attribute ("name", attribute_names, attribute_values);
1445 parent = find_attribute ("parent", attribute_names, attribute_values);
1446 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1447 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1448 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1449 abstract = find_attribute ("abstract", attribute_names, attribute_values);
1452 MISSING_ATTRIBUTE (context, error, element_name, "name");
1453 else if (typename == NULL)
1454 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1455 else if (typeinit == NULL && strcmp (typename, "GObject"))
1456 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1459 GIrNodeInterface *iface;
1461 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT);
1462 ((GIrNode *)iface)->name = g_strdup (name);
1463 iface->gtype_name = g_strdup (typename);
1464 iface->gtype_init = g_strdup (typeinit);
1465 iface->parent = g_strdup (parent);
1467 iface->deprecated = TRUE;
1469 iface->deprecated = FALSE;
1471 iface->abstract = abstract && strcmp (abstract, "1") == 0;
1473 ctx->current_node = (GIrNode *) iface;
1474 ctx->current_module->entries =
1475 g_list_append (ctx->current_module->entries, iface);
1477 state_switch (ctx, STATE_CLASS);
1486 start_type (GMarkupParseContext *context,
1487 const gchar *element_name,
1488 const gchar **attribute_names,
1489 const gchar **attribute_values,
1496 gboolean is_varargs;
1497 GIrNodeType *typenode;
1499 is_array = strcmp (element_name, "array") == 0;
1500 is_varargs = strcmp (element_name, "varargs") == 0;
1502 if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
1505 if (ctx->state == STATE_TYPE)
1508 ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters);
1509 ctx->type_parameters = NULL;
1511 else if (ctx->state == STATE_FUNCTION_PARAMETER ||
1512 ctx->state == STATE_FUNCTION_RETURN ||
1513 ctx->state == STATE_STRUCT_FIELD ||
1514 ctx->state == STATE_UNION_FIELD ||
1515 ctx->state == STATE_CLASS_PROPERTY ||
1516 ctx->state == STATE_CLASS_FIELD ||
1517 ctx->state == STATE_INTERFACE_FIELD ||
1518 ctx->state == STATE_INTERFACE_PROPERTY ||
1519 ctx->state == STATE_BOXED_FIELD ||
1520 ctx->state == STATE_NAMESPACE_CONSTANT ||
1521 ctx->state == STATE_CLASS_CONSTANT ||
1522 ctx->state == STATE_INTERFACE_CONSTANT
1525 state_switch (ctx, STATE_TYPE);
1526 ctx->type_depth = 1;
1529 switch (ctx->current_node->type)
1531 case G_IR_NODE_FUNCTION:
1532 case G_IR_NODE_CALLBACK:
1534 GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
1535 func->is_varargs = TRUE;
1538 case G_IR_NODE_VFUNC:
1540 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
1541 vfunc->is_varargs = TRUE;
1544 /* list others individually rather than with default: so that compiler
1545 * warns if new node types are added without adding them to the switch
1547 case G_IR_NODE_INVALID:
1548 case G_IR_NODE_ENUM:
1549 case G_IR_NODE_FLAGS:
1550 case G_IR_NODE_CONSTANT:
1551 case G_IR_NODE_ERROR_DOMAIN:
1552 case G_IR_NODE_PARAM:
1553 case G_IR_NODE_TYPE:
1554 case G_IR_NODE_PROPERTY:
1555 case G_IR_NODE_SIGNAL:
1556 case G_IR_NODE_VALUE:
1557 case G_IR_NODE_FIELD:
1558 case G_IR_NODE_XREF:
1559 case G_IR_NODE_STRUCT:
1560 case G_IR_NODE_BOXED:
1561 case G_IR_NODE_OBJECT:
1562 case G_IR_NODE_INTERFACE:
1563 case G_IR_NODE_UNION:
1564 g_assert_not_reached ();
1568 ctx->type_stack = NULL;
1569 ctx->type_parameters = NULL;
1572 if (!ctx->current_typed)
1576 G_MARKUP_ERROR_INVALID_CONTENT,
1577 "The element <type> is invalid here");
1590 typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
1592 typenode->tag = GI_TYPE_TAG_ARRAY;
1593 typenode->is_pointer = TRUE;
1594 typenode->is_array = TRUE;
1596 zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
1597 len = find_attribute ("length", attribute_names, attribute_values);
1598 size = find_attribute ("fixed-size", attribute_names, attribute_values);
1600 typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0);
1601 typenode->has_length = len != NULL;
1602 typenode->length = typenode->has_length ? atoi (len) : -1;
1604 typenode->has_size = size != NULL;
1605 typenode->size = typenode->has_size ? atoi (size) : -1;
1609 gboolean is_pointer;
1610 name = find_attribute ("name", attribute_names, attribute_values);
1613 MISSING_ATTRIBUTE (context, error, element_name, "name");
1615 ctype = find_attribute ("c:type", attribute_names, attribute_values);
1616 if (ctype != NULL && strchr (ctype, '*'))
1621 typenode = parse_type (ctx, name);
1623 /* A 'disguised' structure is one where the c:type is a typedef that
1624 * doesn't look like a pointer, but is internally.
1626 if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
1627 g_hash_table_lookup (ctx->disguised_structures, typenode->interface) != NULL)
1631 typenode->is_pointer = is_pointer;
1634 ctx->type_parameters = g_list_append (ctx->type_parameters, typenode);
1640 end_type_top (ParseContext *ctx)
1642 GIrNodeType *typenode;
1644 if (!ctx->type_parameters)
1647 typenode = (GIrNodeType*)ctx->type_parameters->data;
1649 /* Default to pointer for unspecified containers */
1650 if (typenode->tag == GI_TYPE_TAG_ARRAY ||
1651 typenode->tag == GI_TYPE_TAG_GLIST ||
1652 typenode->tag == GI_TYPE_TAG_GSLIST)
1654 if (typenode->parameter_type1 == NULL)
1655 typenode->parameter_type1 = parse_type (ctx, "any");
1657 else if (typenode->tag == GI_TYPE_TAG_GHASH)
1659 if (typenode->parameter_type1 == NULL)
1661 typenode->parameter_type1 = parse_type (ctx, "any");
1662 typenode->parameter_type2 = parse_type (ctx, "any");
1666 switch (ctx->current_typed->type)
1668 case G_IR_NODE_PARAM:
1670 GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed;
1671 param->type = typenode;
1674 case G_IR_NODE_FIELD:
1676 GIrNodeField *field = (GIrNodeField *)ctx->current_typed;
1677 field->type = typenode;
1680 case G_IR_NODE_PROPERTY:
1682 GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed;
1683 property->type = typenode;
1686 case G_IR_NODE_CONSTANT:
1688 GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed;
1689 constant->type = typenode;
1693 g_printerr("current node is %d\n", ctx->current_node->type);
1694 g_assert_not_reached ();
1696 g_list_free (ctx->type_parameters);
1699 ctx->type_depth = 0;
1700 ctx->type_parameters = NULL;
1701 ctx->current_typed = NULL;
1705 end_type_recurse (ParseContext *ctx)
1707 GIrNodeType *parent;
1708 GIrNodeType *param = NULL;
1710 parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data;
1711 if (ctx->type_parameters)
1712 param = (GIrNodeType *) ctx->type_parameters->data;
1714 if (parent->tag == GI_TYPE_TAG_ARRAY ||
1715 parent->tag == GI_TYPE_TAG_GLIST ||
1716 parent->tag == GI_TYPE_TAG_GSLIST)
1718 g_assert (param != NULL);
1720 if (parent->parameter_type1 == NULL)
1721 parent->parameter_type1 = param;
1723 g_assert_not_reached ();
1725 else if (parent->tag == GI_TYPE_TAG_GHASH)
1727 g_assert (param != NULL);
1729 if (parent->parameter_type1 == NULL)
1730 parent->parameter_type1 = param;
1731 else if (parent->parameter_type2 == NULL)
1732 parent->parameter_type2 = param;
1734 g_assert_not_reached ();
1736 g_list_free (ctx->type_parameters);
1737 ctx->type_parameters = (GList *)ctx->type_stack->data;
1738 ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
1742 end_type (ParseContext *ctx)
1744 if (ctx->type_depth == 1)
1747 state_switch (ctx, ctx->prev_state);
1751 end_type_recurse (ctx);
1757 start_return_value (GMarkupParseContext *context,
1758 const gchar *element_name,
1759 const gchar **attribute_names,
1760 const gchar **attribute_values,
1764 if (strcmp (element_name, "return-value") == 0 &&
1765 ctx->state == STATE_FUNCTION)
1767 GIrNodeParam *param;
1768 const gchar *transfer;
1770 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
1773 param->retval = TRUE;
1775 ctx->current_typed = (GIrNode*) param;
1777 state_switch (ctx, STATE_FUNCTION_RETURN);
1779 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1780 parse_param_transfer (param, transfer);
1782 switch (ctx->current_node->type)
1784 case G_IR_NODE_FUNCTION:
1785 case G_IR_NODE_CALLBACK:
1787 GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
1788 func->result = param;
1791 case G_IR_NODE_SIGNAL:
1793 GIrNodeSignal *signal = (GIrNodeSignal *)ctx->current_node;
1794 signal->result = param;
1797 case G_IR_NODE_VFUNC:
1799 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
1800 vfunc->result = param;
1804 g_assert_not_reached ();
1814 start_implements (GMarkupParseContext *context,
1815 const gchar *element_name,
1816 const gchar **attribute_names,
1817 const gchar **attribute_values,
1821 GIrNodeInterface *iface;
1824 if (strcmp (element_name, "implements") != 0 ||
1825 !(ctx->state == STATE_CLASS))
1828 state_switch (ctx, STATE_IMPLEMENTS);
1830 name = find_attribute ("name", attribute_names, attribute_values);
1833 MISSING_ATTRIBUTE (context, error, element_name, "name");
1837 iface = (GIrNodeInterface *)ctx->current_node;
1838 iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
1844 start_glib_signal (GMarkupParseContext *context,
1845 const gchar *element_name,
1846 const gchar **attribute_names,
1847 const gchar **attribute_values,
1851 if (strcmp (element_name, "glib:signal") == 0 &&
1852 (ctx->state == STATE_CLASS ||
1853 ctx->state == STATE_INTERFACE))
1857 const gchar *no_recurse;
1858 const gchar *detailed;
1859 const gchar *action;
1860 const gchar *no_hooks;
1861 const gchar *has_class_closure;
1863 name = find_attribute ("name", attribute_names, attribute_values);
1864 when = find_attribute ("when", attribute_names, attribute_values);
1865 no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values);
1866 detailed = find_attribute ("detailed", attribute_names, attribute_values);
1867 action = find_attribute ("action", attribute_names, attribute_values);
1868 no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values);
1869 has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values);
1872 MISSING_ATTRIBUTE (context, error, element_name, "name");
1875 GIrNodeInterface *iface;
1876 GIrNodeSignal *signal;
1878 signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
1880 ((GIrNode *)signal)->name = g_strdup (name);
1882 signal->run_first = FALSE;
1883 signal->run_last = FALSE;
1884 signal->run_cleanup = FALSE;
1885 if (when == NULL || strcmp (when, "LAST") == 0)
1886 signal->run_last = TRUE;
1887 else if (strcmp (when, "FIRST") == 0)
1888 signal->run_first = TRUE;
1890 signal->run_cleanup = TRUE;
1892 if (no_recurse && strcmp (no_recurse, "1") == 0)
1893 signal->no_recurse = TRUE;
1895 signal->no_recurse = FALSE;
1896 if (detailed && strcmp (detailed, "1") == 0)
1897 signal->detailed = TRUE;
1899 signal->detailed = FALSE;
1900 if (action && strcmp (action, "1") == 0)
1901 signal->action = TRUE;
1903 signal->action = FALSE;
1904 if (no_hooks && strcmp (no_hooks, "1") == 0)
1905 signal->no_hooks = TRUE;
1907 signal->no_hooks = FALSE;
1908 if (has_class_closure && strcmp (has_class_closure, "1") == 0)
1909 signal->has_class_closure = TRUE;
1911 signal->has_class_closure = FALSE;
1913 iface = (GIrNodeInterface *)ctx->current_node;
1914 iface->members = g_list_append (iface->members, signal);
1916 ctx->current_node = (GIrNode *)signal;
1917 state_switch (ctx, STATE_FUNCTION);
1926 start_vfunc (GMarkupParseContext *context,
1927 const gchar *element_name,
1928 const gchar **attribute_names,
1929 const gchar **attribute_values,
1933 if (strcmp (element_name, "vfunc") == 0 &&
1934 (ctx->state == STATE_CLASS ||
1935 ctx->state == STATE_INTERFACE))
1938 const gchar *must_chain_up;
1939 const gchar *override;
1940 const gchar *is_class_closure;
1941 const gchar *offset;
1943 name = find_attribute ("name", attribute_names, attribute_values);
1944 must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values);
1945 override = find_attribute ("override", attribute_names, attribute_values);
1946 is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values);
1947 offset = find_attribute ("offset", attribute_names, attribute_values);
1950 MISSING_ATTRIBUTE (context, error, element_name, "name");
1953 GIrNodeInterface *iface;
1954 GIrNodeVFunc *vfunc;
1956 vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
1958 ((GIrNode *)vfunc)->name = g_strdup (name);
1960 if (must_chain_up && strcmp (must_chain_up, "1") == 0)
1961 vfunc->must_chain_up = TRUE;
1963 vfunc->must_chain_up = FALSE;
1965 if (override && strcmp (override, "always") == 0)
1967 vfunc->must_be_implemented = TRUE;
1968 vfunc->must_not_be_implemented = FALSE;
1970 else if (override && strcmp (override, "never") == 0)
1972 vfunc->must_be_implemented = FALSE;
1973 vfunc->must_not_be_implemented = TRUE;
1977 vfunc->must_be_implemented = FALSE;
1978 vfunc->must_not_be_implemented = FALSE;
1981 if (is_class_closure && strcmp (is_class_closure, "1") == 0)
1982 vfunc->is_class_closure = TRUE;
1984 vfunc->is_class_closure = FALSE;
1987 vfunc->offset = atoi (offset);
1991 iface = (GIrNodeInterface *)ctx->current_node;
1992 iface->members = g_list_append (iface->members, vfunc);
1994 ctx->current_node = (GIrNode *)vfunc;
1995 state_switch (ctx, STATE_FUNCTION);
2005 start_struct (GMarkupParseContext *context,
2006 const gchar *element_name,
2007 const gchar **attribute_names,
2008 const gchar **attribute_values,
2012 if (strcmp (element_name, "record") == 0 &&
2013 ctx->state == STATE_NAMESPACE)
2016 const gchar *deprecated;
2017 const gchar *disguised;
2018 const gchar *gtype_name;
2019 const gchar *gtype_init;
2020 GIrNodeStruct *struct_;
2022 name = find_attribute ("name", attribute_names, attribute_values);
2023 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2024 disguised = find_attribute ("disguised", attribute_names, attribute_values);
2025 gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
2026 gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
2030 MISSING_ATTRIBUTE (context, error, element_name, "name");
2033 if ((gtype_name == NULL && gtype_init != NULL))
2035 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
2038 if ((gtype_name != NULL && gtype_init == NULL))
2040 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
2044 struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
2046 ((GIrNode *)struct_)->name = g_strdup (name);
2048 struct_->deprecated = TRUE;
2050 struct_->deprecated = FALSE;
2052 if (disguised && strcmp (disguised, "1") == 0)
2053 struct_->disguised = TRUE;
2055 struct_->gtype_name = g_strdup (gtype_name);
2056 struct_->gtype_init = g_strdup (gtype_init);
2058 ctx->current_node = (GIrNode *)struct_;
2059 ctx->current_module->entries =
2060 g_list_append (ctx->current_module->entries, struct_);
2062 state_switch (ctx, STATE_STRUCT);
2070 start_union (GMarkupParseContext *context,
2071 const gchar *element_name,
2072 const gchar **attribute_names,
2073 const gchar **attribute_values,
2077 if (strcmp (element_name, "union") == 0 &&
2078 ctx->state == STATE_NAMESPACE)
2081 const gchar *deprecated;
2082 const gchar *typename;
2083 const gchar *typeinit;
2085 name = find_attribute ("name", attribute_names, attribute_values);
2086 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2087 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
2088 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
2091 MISSING_ATTRIBUTE (context, error, element_name, "name");
2094 GIrNodeUnion *union_;
2096 union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
2098 ((GIrNode *)union_)->name = g_strdup (name);
2099 union_->gtype_name = g_strdup (typename);
2100 union_->gtype_init = g_strdup (typeinit);
2102 union_->deprecated = TRUE;
2104 union_->deprecated = FALSE;
2106 ctx->current_node = (GIrNode *)union_;
2107 ctx->current_module->entries =
2108 g_list_append (ctx->current_module->entries, union_);
2110 state_switch (ctx, STATE_UNION);
2118 start_discriminator (GMarkupParseContext *context,
2119 const gchar *element_name,
2120 const gchar **attribute_names,
2121 const gchar **attribute_values,
2125 if (strcmp (element_name, "discriminator") == 0 &&
2126 ctx->state == STATE_UNION)
2129 const gchar *offset;
2131 type = find_attribute ("type", attribute_names, attribute_values);
2132 offset = find_attribute ("offset", attribute_names, attribute_values);
2134 MISSING_ATTRIBUTE (context, error, element_name, "type");
2135 else if (offset == NULL)
2136 MISSING_ATTRIBUTE (context, error, element_name, "offset");
2138 ((GIrNodeUnion *)ctx->current_node)->discriminator_type
2139 = parse_type (ctx, type);
2140 ((GIrNodeUnion *)ctx->current_node)->discriminator_offset
2151 parse_include (GMarkupParseContext *context,
2154 const char *version,
2157 ParseContext sub_ctx = { 0 };
2161 gboolean success = FALSE;
2164 for (l = ctx->include_modules; l; l = l->next)
2166 GIrModule *m = l->data;
2168 if (strcmp (m->name, name) == 0)
2170 if (strcmp (m->version, version) == 0)
2178 G_MARKUP_ERROR_INVALID_CONTENT,
2179 "Module '%s' imported with conflicting versions '%s' and '%s'",
2180 name, m->version, version);
2186 girpath = locate_gir (name, version, ctx->includes);
2188 if (girpath == NULL)
2192 G_MARKUP_ERROR_INVALID_CONTENT,
2193 "Could not find GIR file '%s.gir'; check XDG_DATA_DIRS or use --includedir",
2198 g_debug ("Parsing include %s", girpath);
2200 if (!g_file_get_contents (girpath, &buffer, &length, error))
2207 sub_ctx.state = STATE_START;
2208 sub_ctx.includes = ctx->includes;
2209 sub_ctx.prefix_aliases = TRUE;
2210 sub_ctx.namespace = name;
2211 sub_ctx.aliases = ctx->aliases;
2212 sub_ctx.disguised_structures = ctx->disguised_structures;
2213 sub_ctx.type_depth = 0;
2215 context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL);
2217 if (!g_markup_parse_context_parse (context, buffer, length, error))
2220 if (!g_markup_parse_context_end_parse (context, error))
2223 g_markup_parse_context_free (context);
2225 context = g_markup_parse_context_new (&parser, 0, &sub_ctx, NULL);
2226 if (!g_markup_parse_context_parse (context, buffer, length, error))
2229 if (!g_markup_parse_context_end_parse (context, error))
2235 ctx->include_modules = g_list_concat (ctx->include_modules,
2238 g_markup_parse_context_free (context);
2244 extern GLogLevelFlags logged_levels;
2247 start_element_handler (GMarkupParseContext *context,
2248 const gchar *element_name,
2249 const gchar **attribute_names,
2250 const gchar **attribute_values,
2254 ParseContext *ctx = user_data;
2255 gint line_number, char_number;
2257 if (logged_levels & G_LOG_LEVEL_DEBUG)
2259 GString *tags = g_string_new ("");
2261 for (i = 0; attribute_names[i]; i++)
2262 g_string_append_printf (tags, "%s=\"%s\" ",
2264 attribute_values[i]);
2268 g_string_insert_c (tags, 0, ' ');
2269 g_string_truncate (tags, tags->len - 1);
2271 g_debug ("<%s%s>", element_name, tags->str);
2272 g_string_free (tags, TRUE);
2275 switch (element_name[0])
2278 if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0)
2280 state_switch (ctx, STATE_ALIAS);
2283 if (start_type (context, element_name,
2284 attribute_names, attribute_values,
2289 if (start_enum (context, element_name,
2290 attribute_names, attribute_values,
2295 if (start_function (context, element_name,
2296 attribute_names, attribute_values,
2299 else if (start_constant (context, element_name,
2300 attribute_names, attribute_values,
2303 else if (start_class (context, element_name,
2304 attribute_names, attribute_values,
2307 else if (strcmp (element_name, "class") == 0 &&
2308 ctx->state == STATE_REQUIRES)
2312 name = find_attribute ("name", attribute_names, attribute_values);
2315 MISSING_ATTRIBUTE (context, error, element_name, "name");
2318 GIrNodeInterface *iface;
2320 iface = (GIrNodeInterface *)ctx->current_node;
2321 iface ->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
2329 if (start_discriminator (context, element_name,
2330 attribute_names, attribute_values,
2336 if (start_enum (context, element_name,
2337 attribute_names, attribute_values,
2340 else if (start_errordomain (context, element_name,
2341 attribute_names, attribute_values,
2347 if (start_function (context, element_name,
2348 attribute_names, attribute_values,
2351 else if (start_field (context, element_name,
2352 attribute_names, attribute_values,
2358 if (start_glib_boxed (context, element_name,
2359 attribute_names, attribute_values,
2362 else if (start_glib_signal (context, element_name,
2363 attribute_names, attribute_values,
2369 if (strcmp (element_name, "include") == 0 &&
2370 ctx->state == STATE_REPOSITORY)
2373 const gchar *version;
2375 name = find_attribute ("name", attribute_names, attribute_values);
2376 version = find_attribute ("version", attribute_names, attribute_values);
2380 MISSING_ATTRIBUTE (context, error, element_name, "name");
2383 if (version == NULL)
2385 MISSING_ATTRIBUTE (context, error, element_name, "version");
2389 if (!parse_include (context, ctx, name, version, error))
2392 ctx->dependencies = g_list_prepend (ctx->dependencies,
2393 g_strdup_printf ("%s-%s", name, version));
2396 state_switch (ctx, STATE_INCLUDE);
2399 if (start_interface (context, element_name,
2400 attribute_names, attribute_values,
2403 else if (start_implements (context, element_name,
2404 attribute_names, attribute_values,
2410 if (start_function (context, element_name,
2411 attribute_names, attribute_values,
2414 else if (start_member (context, element_name,
2415 attribute_names, attribute_values,
2421 if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2423 const gchar *name, *version, *shared_library;
2425 name = find_attribute ("name", attribute_names, attribute_values);
2426 version = find_attribute ("version", attribute_names, attribute_values);
2427 shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2430 MISSING_ATTRIBUTE (context, error, element_name, "name");
2431 else if (version == NULL)
2432 MISSING_ATTRIBUTE (context, error, element_name, "version");
2435 ctx->current_module = g_ir_module_new (name, version, shared_library);
2436 ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2437 ctx->current_module->dependencies = ctx->dependencies;
2438 ctx->current_module->include_modules = g_list_copy (ctx->include_modules);
2440 state_switch (ctx, STATE_NAMESPACE);
2447 if (start_property (context, element_name,
2448 attribute_names, attribute_values,
2451 else if (strcmp (element_name, "parameters") == 0 &&
2452 ctx->state == STATE_FUNCTION)
2454 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2458 else if (start_parameter (context, element_name,
2459 attribute_names, attribute_values,
2466 if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
2468 const gchar *version;
2470 version = find_attribute ("version", attribute_names, attribute_values);
2472 if (version == NULL)
2473 MISSING_ATTRIBUTE (context, error, element_name, "version");
2474 else if (strcmp (version, "1.0") != 0)
2477 G_MARKUP_ERROR_INVALID_CONTENT,
2478 "Unsupported version '%s'",
2481 state_switch (ctx, STATE_REPOSITORY);
2485 else if (start_return_value (context, element_name,
2486 attribute_names, attribute_values,
2489 else if (strcmp (element_name, "requires") == 0 &&
2490 ctx->state == STATE_INTERFACE)
2492 state_switch (ctx, STATE_REQUIRES);
2496 else if (start_struct (context, element_name,
2497 attribute_names, attribute_values,
2503 if (start_union (context, element_name,
2504 attribute_names, attribute_values,
2510 if (start_type (context, element_name,
2511 attribute_names, attribute_values,
2517 if (start_vfunc (context, element_name,
2518 attribute_names, attribute_values,
2521 if (start_type (context, element_name,
2522 attribute_names, attribute_values,
2528 g_markup_parse_context_get_position (context, &line_number, &char_number);
2530 if (error && *error == NULL)
2533 G_MARKUP_ERROR_UNKNOWN_ELEMENT,
2534 "Unexpected start tag '%s' on line %d char %d; current state=%d",
2536 line_number, char_number, ctx->state);
2541 g_markup_parse_context_get_position (context, &line_number, &char_number);
2543 fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message);
2544 backtrace_stderr ();
2549 require_one_of_end_elements (GMarkupParseContext *context,
2551 const char *actual_name,
2556 int line_number, char_number;
2557 const char *expected;
2558 gboolean matched = FALSE;
2560 va_start (args, error);
2562 while ((expected = va_arg (args, const char*)) != NULL)
2564 if (strcmp (expected, actual_name) == 0)
2576 g_markup_parse_context_get_position (context, &line_number, &char_number);
2579 G_MARKUP_ERROR_INVALID_CONTENT,
2580 "Unexpected end tag '%s' on line %d char %d; current state=%d",
2582 line_number, char_number, ctx->state);
2588 require_end_element (GMarkupParseContext *context,
2590 const char *expected_name,
2591 const char *actual_name,
2594 return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
2598 end_element_handler (GMarkupParseContext *context,
2599 const gchar *element_name,
2603 ParseContext *ctx = user_data;
2605 g_debug ("</%s>", element_name);
2611 /* no need to GError here, GMarkup already catches this */
2614 case STATE_REPOSITORY:
2615 state_switch (ctx, STATE_END);
2619 if (require_end_element (context, ctx, "include", element_name, error))
2621 state_switch (ctx, STATE_REPOSITORY);
2625 case STATE_NAMESPACE:
2626 if (require_end_element (context, ctx, "namespace", element_name, error))
2628 ctx->current_module = NULL;
2629 state_switch (ctx, STATE_REPOSITORY);
2634 if (require_end_element (context, ctx, "alias", element_name, error))
2636 state_switch (ctx, STATE_NAMESPACE);
2640 case STATE_FUNCTION_RETURN:
2641 if (strcmp ("type", element_name) == 0)
2643 if (require_end_element (context, ctx, "return-value", element_name, error))
2645 state_switch (ctx, STATE_FUNCTION);
2649 case STATE_FUNCTION_PARAMETERS:
2650 if (require_end_element (context, ctx, "parameters", element_name, error))
2652 state_switch (ctx, STATE_FUNCTION);
2656 case STATE_FUNCTION_PARAMETER:
2657 if (strcmp ("type", element_name) == 0)
2659 if (require_end_element (context, ctx, "parameter", element_name, error))
2661 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2665 case STATE_FUNCTION:
2667 gboolean current_is_toplevel;
2668 GList *last = g_list_last (ctx->current_module->entries);
2670 current_is_toplevel = ctx->current_node == last->data;
2672 if (current_is_toplevel)
2674 ctx->current_node = NULL;
2675 state_switch (ctx, STATE_NAMESPACE);
2679 ctx->current_node = g_list_last (ctx->current_module->entries)->data;
2680 if (ctx->current_node->type == G_IR_NODE_INTERFACE)
2681 state_switch (ctx, STATE_INTERFACE);
2682 else if (ctx->current_node->type == G_IR_NODE_OBJECT)
2683 state_switch (ctx, STATE_CLASS);
2684 else if (ctx->current_node->type == G_IR_NODE_BOXED)
2685 state_switch (ctx, STATE_BOXED);
2686 else if (ctx->current_node->type == G_IR_NODE_STRUCT)
2687 state_switch (ctx, STATE_STRUCT);
2688 else if (ctx->current_node->type == G_IR_NODE_UNION)
2689 state_switch (ctx, STATE_UNION);
2692 int line_number, char_number;
2693 g_markup_parse_context_get_position (context, &line_number, &char_number);
2696 G_MARKUP_ERROR_INVALID_CONTENT,
2697 "Unexpected end tag '%s' on line %d char %d",
2699 line_number, char_number);
2705 case STATE_CLASS_FIELD:
2706 if (strcmp ("type", element_name) == 0)
2708 if (require_end_element (context, ctx, "field", element_name, error))
2710 state_switch (ctx, STATE_CLASS);
2714 case STATE_CLASS_PROPERTY:
2715 if (strcmp ("type", element_name) == 0)
2717 if (require_end_element (context, ctx, "property", element_name, error))
2719 state_switch (ctx, STATE_CLASS);
2724 if (require_end_element (context, ctx, "class", element_name, error))
2726 ctx->current_node = NULL;
2727 state_switch (ctx, STATE_NAMESPACE);
2731 case STATE_ERRORDOMAIN:
2732 if (require_end_element (context, ctx, "errordomain", element_name, error))
2734 ctx->current_node = NULL;
2735 state_switch (ctx, STATE_NAMESPACE);
2739 case STATE_INTERFACE_PROPERTY:
2740 if (strcmp ("type", element_name) == 0)
2742 if (require_end_element (context, ctx, "property", element_name, error))
2744 state_switch (ctx, STATE_INTERFACE);
2748 case STATE_INTERFACE_FIELD:
2749 if (strcmp ("type", element_name) == 0)
2751 if (require_end_element (context, ctx, "field", element_name, error))
2753 state_switch (ctx, STATE_INTERFACE);
2757 case STATE_INTERFACE:
2758 if (require_end_element (context, ctx, "interface", element_name, error))
2760 ctx->current_node = NULL;
2761 state_switch (ctx, STATE_NAMESPACE);
2766 if (strcmp ("member", element_name) == 0)
2768 else if (require_one_of_end_elements (context, ctx,
2769 element_name, error, "enumeration",
2772 ctx->current_node = NULL;
2773 state_switch (ctx, STATE_NAMESPACE);
2778 if (require_end_element (context, ctx, "glib:boxed", element_name, error))
2780 ctx->current_node = NULL;
2781 state_switch (ctx, STATE_NAMESPACE);
2785 case STATE_BOXED_FIELD:
2786 if (strcmp ("type", element_name) == 0)
2788 if (require_end_element (context, ctx, "field", element_name, error))
2790 state_switch (ctx, STATE_BOXED);
2794 case STATE_STRUCT_FIELD:
2795 if (strcmp ("type", element_name) == 0)
2797 if (require_end_element (context, ctx, "field", element_name, error))
2799 state_switch (ctx, STATE_STRUCT);
2804 if (require_end_element (context, ctx, "record", element_name, error))
2806 ctx->current_node = NULL;
2807 state_switch (ctx, STATE_NAMESPACE);
2811 case STATE_UNION_FIELD:
2812 if (strcmp ("type", element_name) == 0)
2814 if (require_end_element (context, ctx, "field", element_name, error))
2816 state_switch (ctx, STATE_UNION);
2821 if (require_end_element (context, ctx, "union", element_name, error))
2823 ctx->current_node = NULL;
2824 state_switch (ctx, STATE_NAMESPACE);
2827 case STATE_IMPLEMENTS:
2828 if (strcmp ("interface", element_name) == 0)
2830 if (require_end_element (context, ctx, "implements", element_name, error))
2831 state_switch (ctx, STATE_CLASS);
2833 case STATE_REQUIRES:
2834 if (require_end_element (context, ctx, "requires", element_name, error))
2835 state_switch (ctx, STATE_INTERFACE);
2837 case STATE_NAMESPACE_CONSTANT:
2838 case STATE_CLASS_CONSTANT:
2839 case STATE_INTERFACE_CONSTANT:
2840 if (strcmp ("type", element_name) == 0)
2842 if (require_end_element (context, ctx, "constant", element_name, error))
2844 ctx->current_node = NULL;
2847 case STATE_NAMESPACE_CONSTANT:
2848 state_switch (ctx, STATE_NAMESPACE);
2850 case STATE_CLASS_CONSTANT:
2851 state_switch (ctx, STATE_CLASS);
2853 case STATE_INTERFACE_CONSTANT:
2854 state_switch (ctx, STATE_INTERFACE);
2857 g_assert_not_reached ();
2863 if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
2864 (strcmp ("varargs", element_name) == 0))
2870 g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
2875 text_handler (GMarkupParseContext *context,
2881 /* FIXME warn about non-whitespace text */
2885 cleanup (GMarkupParseContext *context,
2889 ParseContext *ctx = user_data;
2892 for (m = ctx->modules; m; m = m->next)
2893 g_ir_module_free (m->data);
2894 g_list_free (ctx->modules);
2895 ctx->modules = NULL;
2897 ctx->current_module = NULL;
2901 post_filter_varargs_functions (GList *list)
2909 GIrNode *node = iter->data;
2913 if (node->type == G_IR_NODE_FUNCTION)
2915 if (((GIrNodeFunction*)node)->is_varargs)
2917 list = g_list_delete_link (list, link);
2925 post_filter (GIrModule *module)
2929 module->entries = post_filter_varargs_functions (module->entries);
2930 iter = module->entries;
2933 GIrNode *node = iter->data;
2937 if (node->type == G_IR_NODE_OBJECT ||
2938 node->type == G_IR_NODE_INTERFACE)
2940 GIrNodeInterface *iface = (GIrNodeInterface*)node;
2941 iface->members = post_filter_varargs_functions (iface->members);
2943 else if (node->type == G_IR_NODE_BOXED)
2945 GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
2946 boxed->members = post_filter_varargs_functions (boxed->members);
2948 else if (node->type == G_IR_NODE_STRUCT)
2950 GIrNodeStruct *iface = (GIrNodeStruct*)node;
2951 iface->members = post_filter_varargs_functions (iface->members);
2953 else if (node->type == G_IR_NODE_UNION)
2955 GIrNodeUnion *iface = (GIrNodeUnion*)node;
2956 iface->members = post_filter_varargs_functions (iface->members);
2962 g_ir_parse_string (const gchar *namespace,
2963 const gchar *const *includes,
2964 const gchar *buffer,
2968 ParseContext ctx = { 0 };
2969 GMarkupParseContext *context;
2971 ctx.state = STATE_START;
2972 ctx.includes = includes;
2973 ctx.prefix_aliases = FALSE;
2974 ctx.namespace = namespace;
2975 ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
2976 ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
2978 ctx.dependencies = NULL;
2979 ctx.current_module = NULL;
2981 context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
2983 if (!g_markup_parse_context_parse (context, buffer, length, error))
2986 if (!g_markup_parse_context_end_parse (context, error))
2989 g_markup_parse_context_free (context);
2991 context = g_markup_parse_context_new (&parser, 0, &ctx, NULL);
2992 if (!g_markup_parse_context_parse (context, buffer, length, error))
2995 if (!g_markup_parse_context_end_parse (context, error))
3000 g_hash_table_destroy (ctx.aliases);
3001 g_hash_table_destroy (ctx.disguised_structures);
3003 g_markup_parse_context_free (context);
3009 g_ir_parse_file (const gchar *filename,
3010 const gchar *const *includes,
3020 if (!g_str_has_suffix (filename, ".gir"))
3024 G_MARKUP_ERROR_INVALID_CONTENT,
3025 "Expected filename to end with '.gir'");
3029 g_debug ("[parsing] filename %s", filename);
3031 slash = g_strrstr (filename, "/");
3033 namespace = g_strdup (filename);
3035 namespace = g_strdup (slash+1);
3036 namespace[strlen(namespace)-4] = '\0';
3038 if (!g_file_get_contents (filename, &buffer, &length, error))
3041 modules = g_ir_parse_string (namespace, includes, buffer, length, error);
3043 for (iter = modules; iter; iter = iter->next)
3045 post_filter ((GIrModule*)iter->data);