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"
34 GList *parsed_modules; /* All previously parsed modules */
47 STATE_FUNCTION_RETURN,
48 STATE_FUNCTION_PARAMETERS,
49 STATE_FUNCTION_PARAMETER, /* 10 */
54 STATE_INTERFACE_PROPERTY, /* 15 */
55 STATE_INTERFACE_FIELD,
59 STATE_BOXED_FIELD, /* 20 */
64 STATE_UNION_FIELD, /* 25 */
65 STATE_NAMESPACE_CONSTANT,
67 STATE_INTERFACE_CONSTANT,
72 typedef struct _ParseContext ParseContext;
78 ParseState prev_state;
81 GList *include_modules;
84 GHashTable *disguised_structures;
86 const char *namespace;
87 GIrModule *current_module;
88 GIrNode *current_node;
89 GIrNode *current_typed;
92 GList *type_parameters;
96 static void start_element_handler (GMarkupParseContext *context,
97 const gchar *element_name,
98 const gchar **attribute_names,
99 const gchar **attribute_values,
102 static void end_element_handler (GMarkupParseContext *context,
103 const gchar *element_name,
106 static void text_handler (GMarkupParseContext *context,
111 static void cleanup (GMarkupParseContext *context,
115 static GMarkupParser markup_parser =
117 start_element_handler,
125 start_alias (GMarkupParseContext *context,
126 const gchar *element_name,
127 const gchar **attribute_names,
128 const gchar **attribute_values,
132 static const gchar *find_attribute (const gchar *name,
133 const gchar **attribute_names,
134 const gchar **attribute_values);
138 g_ir_parser_new (void)
140 GIrParser *parser = g_slice_new0 (GIrParser);
146 g_ir_parser_free (GIrParser *parser)
150 if (parser->includes)
151 g_strfreev (parser->includes);
153 for (l = parser->parsed_modules; l; l = l->next)
154 g_ir_module_free (l->data);
156 g_slice_free (GIrParser, parser);
160 g_ir_parser_set_includes (GIrParser *parser,
161 const gchar *const *includes)
163 if (parser->includes)
164 g_strfreev (parser->includes);
166 parser->includes = g_strdupv ((char **)includes);
170 firstpass_start_element_handler (GMarkupParseContext *context,
171 const gchar *element_name,
172 const gchar **attribute_names,
173 const gchar **attribute_values,
177 ParseContext *ctx = user_data;
179 if (strcmp (element_name, "alias") == 0)
181 start_alias (context, element_name, attribute_names, attribute_values,
184 else if (strcmp (element_name, "record") == 0)
187 const gchar *disguised;
189 name = find_attribute ("name", attribute_names, attribute_values);
190 disguised = find_attribute ("disguised", attribute_names, attribute_values);
192 if (disguised && strcmp (disguised, "1") == 0)
196 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
197 g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
203 firstpass_end_element_handler (GMarkupParseContext *context,
204 const gchar *element_name,
210 static GMarkupParser firstpass_parser =
212 firstpass_start_element_handler,
213 firstpass_end_element_handler,
220 locate_gir (GIrParser *parser,
224 const gchar *const *datadirs;
225 const gchar *const *dir;
229 datadirs = g_get_system_data_dirs ();
231 girname = g_strdup_printf ("%s-%s.gir", name, version);
233 if (parser->includes != NULL)
235 for (dir = (const gchar *const *)parser->includes; *dir; dir++)
237 path = g_build_filename (*dir, girname, NULL);
238 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
244 for (dir = datadirs; *dir; dir++)
246 path = g_build_filename (*dir, "gir", girname, NULL);
247 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
256 #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \
258 int line_number, char_number; \
259 g_markup_parse_context_get_position (context, &line_number, &char_number); \
260 g_set_error (error, \
262 G_MARKUP_ERROR_INVALID_CONTENT, \
263 "Line %d, character %d: The attribute '%s' on the element '%s' must be specified", \
264 line_number, char_number, attribute, element); \
268 backtrace_stderr (void)
270 #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
276 size = backtrace (array, 50);
277 strings = (char**) backtrace_symbols (array, size);
279 fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size);
281 for (i = 0; i < size; i++)
282 fprintf (stderr, "%s\n", strings[i]);
284 fprintf (stderr, "--- END BACKTRACE ---\n", size);
292 find_attribute (const gchar *name,
293 const gchar **attribute_names,
294 const gchar **attribute_values)
298 for (i = 0; attribute_names[i] != NULL; i++)
299 if (strcmp (attribute_names[i], name) == 0)
300 return attribute_values[i];
306 state_switch (ParseContext *ctx, ParseState newstate)
308 g_debug ("State: %d", newstate);
309 ctx->prev_state = ctx->state;
310 ctx->state = newstate;
313 static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
314 gboolean in_gobject);
322 static BasicTypeInfo basic_types[] = {
323 { "none", GI_TYPE_TAG_VOID, 0 },
324 { "any", GI_TYPE_TAG_VOID, 1 },
326 { "bool", GI_TYPE_TAG_BOOLEAN, 0 },
327 { "char", GI_TYPE_TAG_INT8, 0 },
328 { "int8", GI_TYPE_TAG_INT8, 0 },
329 { "uint8", GI_TYPE_TAG_UINT8, 0 },
330 { "int16", GI_TYPE_TAG_INT16, 0 },
331 { "uint16", GI_TYPE_TAG_UINT16, 0 },
332 { "int32", GI_TYPE_TAG_INT32, 0 },
333 { "uint32", GI_TYPE_TAG_UINT32, 0 },
334 { "int64", GI_TYPE_TAG_INT64, 0 },
335 { "uint64", GI_TYPE_TAG_UINT64, 0 },
336 { "int", GI_TYPE_TAG_INT, 0 },
337 { "uint", GI_TYPE_TAG_UINT, 0 },
338 { "long", GI_TYPE_TAG_LONG, 0 },
339 { "ulong", GI_TYPE_TAG_ULONG, 0 },
340 { "ssize_t", GI_TYPE_TAG_SSIZE, 0 },
341 { "ssize", GI_TYPE_TAG_SSIZE, 0 },
342 { "size_t", GI_TYPE_TAG_SIZE, 0 },
343 { "size", GI_TYPE_TAG_SIZE, 0 },
344 { "float", GI_TYPE_TAG_FLOAT, 0 },
345 { "double", GI_TYPE_TAG_DOUBLE, 0 },
346 { "time_t", GI_TYPE_TAG_TIME_T, 0 },
347 { "GType", GI_TYPE_TAG_GTYPE, 0 },
348 { "utf8", GI_TYPE_TAG_UTF8, 1 },
349 { "filename", GI_TYPE_TAG_FILENAME,1 },
352 static const BasicTypeInfo *
353 parse_basic (const char *str)
356 gint n_basic = G_N_ELEMENTS (basic_types);
358 for (i = 0; i < n_basic; i++)
360 if (g_str_has_prefix (str, basic_types[i].str))
361 return &(basic_types[i]);
367 parse_type_internal (const gchar *str, char **next, gboolean in_glib,
370 const BasicTypeInfo *basic;
372 char *temporary_type = NULL;
374 type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
376 type->unparsed = g_strdup (str);
378 /* See comment below on GLib.List handling */
379 if (in_gobject && strcmp (str, "Type") == 0)
381 temporary_type = g_strdup ("GLib.Type");
382 str = temporary_type;
385 basic = parse_basic (str);
388 type->is_basic = TRUE;
389 type->tag = basic->tag;
390 type->is_pointer = basic->pointer;
392 str += strlen(basic->str);
396 /* If we're inside GLib, handle "List" etc. by prefixing with
397 * "GLib." so the parsing code below doesn't have to get more
400 if (g_str_has_prefix (str, "List<") ||
401 strcmp (str, "List") == 0)
403 temporary_type = g_strdup_printf ("GLib.List%s", str + 4);
404 str = temporary_type;
406 else if (g_str_has_prefix (str, "SList<") ||
407 strcmp (str, "SList") == 0)
409 temporary_type = g_strdup_printf ("GLib.SList%s", str + 5);
410 str = temporary_type;
412 else if (g_str_has_prefix (str, "HashTable<") ||
413 strcmp (str, "HashTable") == 0)
415 temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9);
416 str = temporary_type;
418 else if (g_str_has_prefix (str, "Error<") ||
419 strcmp (str, "Error") == 0)
421 temporary_type = g_strdup_printf ("GLib.Error%s", str + 5);
422 str = temporary_type;
427 /* found a basic type */;
428 else if (g_str_has_prefix (str, "GLib.List") ||
429 g_str_has_prefix (str, "GLib.SList"))
431 str += strlen ("GLib.");
432 if (g_str_has_prefix (str, "List"))
434 type->tag = GI_TYPE_TAG_GLIST;
435 type->is_glist = TRUE;
436 type->is_pointer = TRUE;
437 str += strlen ("List");
441 type->tag = GI_TYPE_TAG_GSLIST;
442 type->is_gslist = TRUE;
443 type->is_pointer = TRUE;
444 str += strlen ("SList");
447 else if (g_str_has_prefix (str, "GLib.HashTable"))
449 str += strlen ("GLib.");
451 type->tag = GI_TYPE_TAG_GHASH;
452 type->is_ghashtable = TRUE;
453 type->is_pointer = TRUE;
454 str += strlen ("HashTable");
456 else if (g_str_has_prefix (str, "GLib.Error"))
458 str += strlen ("GLib.");
460 type->tag = GI_TYPE_TAG_ERROR;
461 type->is_error = TRUE;
462 type->is_pointer = TRUE;
463 str += strlen ("Error");
470 end = strchr (str, '>');
471 tmp = g_strndup (str, end - str);
472 type->errors = g_strsplit (tmp, ",", 0);
480 type->tag = GI_TYPE_TAG_INTERFACE;
481 type->is_interface = TRUE;
482 const char *start = str;
484 /* must be an interface type */
485 while (g_ascii_isalnum (*str) ||
492 type->interface = g_strndup (start, str - start);
497 g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR);
498 g_free (temporary_type);
502 g_ir_node_free ((GIrNode *)type);
503 g_free (temporary_type);
508 resolve_aliases (ParseContext *ctx, const gchar *type)
512 GSList *seen_values = NULL;
516 if (strchr (type, '.') == NULL)
518 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
527 seen_values = g_slist_prepend (seen_values, (char*)lookup);
528 while (g_hash_table_lookup_extended (ctx->current_module->aliases, lookup, &orig, &value))
530 g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
532 if (g_slist_find_custom (seen_values, lookup,
533 (GCompareFunc)strcmp) != NULL)
535 seen_values = g_slist_prepend (seen_values, (gchar*)lookup);
537 g_slist_free (seen_values);
539 if (lookup == prefixed)
548 is_disguised_structure (ParseContext *ctx, const gchar *type)
554 if (strchr (type, '.') == NULL)
556 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
565 result = g_hash_table_lookup (ctx->current_module->disguised_structures,
574 parse_type (ParseContext *ctx, const gchar *type)
577 const BasicTypeInfo *basic;
578 gboolean in_glib, in_gobject;
580 in_glib = strcmp (ctx->namespace, "GLib") == 0;
581 in_gobject = strcmp (ctx->namespace, "GObject") == 0;
583 /* Do not search aliases for basic types */
584 basic = parse_basic (type);
586 type = resolve_aliases (ctx, type);
588 node = parse_type_internal (type, NULL, in_glib, in_gobject);
590 g_debug ("Parsed type: %s => %d", type, node->tag);
592 g_critical ("Failed to parse type: '%s'", type);
598 start_glib_boxed (GMarkupParseContext *context,
599 const gchar *element_name,
600 const gchar **attribute_names,
601 const gchar **attribute_values,
606 const gchar *typename;
607 const gchar *typeinit;
608 const gchar *deprecated;
611 if (!(strcmp (element_name, "glib:boxed") == 0 &&
612 ctx->state == STATE_NAMESPACE))
615 name = find_attribute ("glib:name", attribute_names, attribute_values);
616 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
617 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
618 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
622 MISSING_ATTRIBUTE (context, error, element_name, "glib:name");
625 else if (typename == NULL)
627 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
630 else if (typeinit == NULL)
632 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
636 boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED);
638 ((GIrNode *)boxed)->name = g_strdup (name);
639 boxed->gtype_name = g_strdup (typename);
640 boxed->gtype_init = g_strdup (typeinit);
642 boxed->deprecated = TRUE;
644 boxed->deprecated = FALSE;
646 ctx->current_node = (GIrNode *)boxed;
647 ctx->current_module->entries =
648 g_list_append (ctx->current_module->entries, boxed);
650 state_switch (ctx, STATE_BOXED);
656 start_function (GMarkupParseContext *context,
657 const gchar *element_name,
658 const gchar **attribute_names,
659 const gchar **attribute_values,
665 const gchar *deprecated;
667 GIrNodeFunction *function;
668 gboolean found = FALSE;
672 case STATE_NAMESPACE:
673 found = (strcmp (element_name, "function") == 0 ||
674 strcmp (element_name, "callback") == 0);
677 found = strcmp (element_name, "function") == 0;
682 found = (found || strcmp (element_name, "constructor") == 0);
684 case STATE_INTERFACE:
686 strcmp (element_name, "method") == 0 ||
687 strcmp (element_name, "callback") == 0);
696 name = find_attribute ("name", attribute_names, attribute_values);
697 symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
698 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
699 throws = find_attribute ("throws", attribute_names, attribute_values);
703 MISSING_ATTRIBUTE (context, error, element_name, "name");
706 else if (strcmp (element_name, "callback") != 0 && symbol == NULL)
708 MISSING_ATTRIBUTE (context, error, element_name, "c:identifier");
712 function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION);
714 ((GIrNode *)function)->name = g_strdup (name);
715 function->symbol = g_strdup (symbol);
716 function->parameters = NULL;
718 function->deprecated = TRUE;
720 function->deprecated = FALSE;
722 if (strcmp (element_name, "method") == 0 ||
723 strcmp (element_name, "constructor") == 0)
725 function->is_method = TRUE;
727 if (strcmp (element_name, "constructor") == 0)
728 function->is_constructor = TRUE;
730 function->is_constructor = FALSE;
734 function->is_method = FALSE;
735 function->is_setter = FALSE;
736 function->is_getter = FALSE;
737 function->is_constructor = FALSE;
738 if (strcmp (element_name, "callback") == 0)
739 ((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
742 if (throws && strcmp (throws, "1") == 0)
743 function->throws = TRUE;
745 function->throws = FALSE;
747 if (ctx->current_node == NULL)
749 ctx->current_module->entries =
750 g_list_append (ctx->current_module->entries, function);
753 switch (ctx->current_node->type)
755 case G_IR_NODE_INTERFACE:
756 case G_IR_NODE_OBJECT:
758 GIrNodeInterface *iface;
760 iface = (GIrNodeInterface *)ctx->current_node;
761 iface->members = g_list_append (iface->members, function);
764 case G_IR_NODE_BOXED:
768 boxed = (GIrNodeBoxed *)ctx->current_node;
769 boxed->members = g_list_append (boxed->members, function);
772 case G_IR_NODE_STRUCT:
774 GIrNodeStruct *struct_;
776 struct_ = (GIrNodeStruct *)ctx->current_node;
777 struct_->members = g_list_append (struct_->members, function); }
779 case G_IR_NODE_UNION:
781 GIrNodeUnion *union_;
783 union_ = (GIrNodeUnion *)ctx->current_node;
784 union_->members = g_list_append (union_->members, function);
788 g_assert_not_reached ();
791 ctx->current_node = (GIrNode *)function;
792 state_switch (ctx, STATE_FUNCTION);
798 parse_param_transfer (GIrNodeParam *param, const gchar *transfer)
800 if (transfer == NULL)
802 g_warning ("required attribute 'transfer-ownership' missing");
804 else if (strcmp (transfer, "none") == 0)
806 param->transfer = FALSE;
807 param->shallow_transfer = FALSE;
809 else if (strcmp (transfer, "container") == 0)
811 param->transfer = FALSE;
812 param->shallow_transfer = TRUE;
814 else if (strcmp (transfer, "full") == 0)
816 param->transfer = TRUE;
817 param->shallow_transfer = FALSE;
821 g_warning ("Unknown transfer-ownership value: %s", transfer);
826 start_parameter (GMarkupParseContext *context,
827 const gchar *element_name,
828 const gchar **attribute_names,
829 const gchar **attribute_values,
834 const gchar *direction;
837 const gchar *optional;
838 const gchar *allow_none;
839 const gchar *transfer;
841 const gchar *closure;
842 const gchar *destroy;
845 if (!(strcmp (element_name, "parameter") == 0 &&
846 ctx->state == STATE_FUNCTION_PARAMETERS))
849 name = find_attribute ("name", attribute_names, attribute_values);
850 direction = find_attribute ("direction", attribute_names, attribute_values);
851 retval = find_attribute ("retval", attribute_names, attribute_values);
852 dipper = find_attribute ("dipper", attribute_names, attribute_values);
853 optional = find_attribute ("optional", attribute_names, attribute_values);
854 allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
855 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
856 scope = find_attribute ("scope", attribute_names, attribute_values);
857 closure = find_attribute ("closure", attribute_names, attribute_values);
858 destroy = find_attribute ("destroy", attribute_names, attribute_values);
863 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
865 ctx->current_typed = (GIrNode*) param;
866 ctx->current_typed->name = g_strdup (name);
868 state_switch (ctx, STATE_FUNCTION_PARAMETER);
870 if (direction && strcmp (direction, "out") == 0)
875 else if (direction && strcmp (direction, "inout") == 0)
886 if (retval && strcmp (retval, "1") == 0)
887 param->retval = TRUE;
889 param->retval = FALSE;
891 if (dipper && strcmp (dipper, "1") == 0)
892 param->dipper = TRUE;
894 param->dipper = FALSE;
896 if (optional && strcmp (optional, "1") == 0)
897 param->optional = TRUE;
899 param->optional = FALSE;
901 if (allow_none && strcmp (allow_none, "1") == 0)
902 param->allow_none = TRUE;
904 param->allow_none = FALSE;
906 parse_param_transfer (param, transfer);
908 if (scope && strcmp (scope, "call") == 0)
909 param->scope = GI_SCOPE_TYPE_CALL;
910 else if (scope && strcmp (scope, "object") == 0)
911 param->scope = GI_SCOPE_TYPE_OBJECT;
912 else if (scope && strcmp (scope, "async") == 0)
913 param->scope = GI_SCOPE_TYPE_ASYNC;
914 else if (scope && strcmp (scope, "notified") == 0)
915 param->scope = GI_SCOPE_TYPE_NOTIFIED;
917 param->scope = GI_SCOPE_TYPE_INVALID;
919 param->closure = closure ? atoi (closure) : -1;
920 param->destroy = destroy ? atoi (destroy) : -1;
922 ((GIrNode *)param)->name = g_strdup (name);
924 switch (ctx->current_node->type)
926 case G_IR_NODE_FUNCTION:
927 case G_IR_NODE_CALLBACK:
929 GIrNodeFunction *func;
931 func = (GIrNodeFunction *)ctx->current_node;
932 func->parameters = g_list_append (func->parameters, param);
935 case G_IR_NODE_SIGNAL:
937 GIrNodeSignal *signal;
939 signal = (GIrNodeSignal *)ctx->current_node;
940 signal->parameters = g_list_append (signal->parameters, param);
943 case G_IR_NODE_VFUNC:
947 vfunc = (GIrNodeVFunc *)ctx->current_node;
948 vfunc->parameters = g_list_append (vfunc->parameters, param);
952 g_assert_not_reached ();
959 start_field (GMarkupParseContext *context,
960 const gchar *element_name,
961 const gchar **attribute_names,
962 const gchar **attribute_values,
967 const gchar *readable;
968 const gchar *writable;
979 case STATE_INTERFACE:
985 if (strcmp (element_name, "field") != 0)
988 name = find_attribute ("name", attribute_names, attribute_values);
989 readable = find_attribute ("readable", attribute_names, attribute_values);
990 writable = find_attribute ("writable", attribute_names, attribute_values);
991 bits = find_attribute ("bits", attribute_names, attribute_values);
992 branch = find_attribute ("branch", attribute_names, attribute_values);
996 MISSING_ATTRIBUTE (context, error, element_name, "name");
1000 field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD);
1001 ctx->current_typed = (GIrNode*) field;
1002 ((GIrNode *)field)->name = g_strdup (name);
1003 /* Fields are assumed to be read-only.
1004 * (see also girwriter.py and generate.c)
1006 field->readable = readable == NULL || strcmp (readable, "0") == 0;
1007 field->writable = writable != NULL && strcmp (writable, "1") == 0;
1010 field->bits = atoi (bits);
1014 switch (ctx->current_node->type)
1016 case G_IR_NODE_OBJECT:
1018 GIrNodeInterface *iface;
1020 iface = (GIrNodeInterface *)ctx->current_node;
1021 iface->members = g_list_append (iface->members, field);
1022 state_switch (ctx, STATE_CLASS_FIELD);
1025 case G_IR_NODE_INTERFACE:
1027 GIrNodeInterface *iface;
1029 iface = (GIrNodeInterface *)ctx->current_node;
1030 iface->members = g_list_append (iface->members, field);
1031 state_switch (ctx, STATE_INTERFACE_FIELD);
1034 case G_IR_NODE_BOXED:
1036 GIrNodeBoxed *boxed;
1038 boxed = (GIrNodeBoxed *)ctx->current_node;
1039 boxed->members = g_list_append (boxed->members, field);
1040 state_switch (ctx, STATE_BOXED_FIELD);
1043 case G_IR_NODE_STRUCT:
1045 GIrNodeStruct *struct_;
1047 struct_ = (GIrNodeStruct *)ctx->current_node;
1048 struct_->members = g_list_append (struct_->members, field);
1049 state_switch (ctx, STATE_STRUCT_FIELD);
1052 case G_IR_NODE_UNION:
1054 GIrNodeUnion *union_;
1056 union_ = (GIrNodeUnion *)ctx->current_node;
1057 union_->members = g_list_append (union_->members, field);
1060 GIrNodeConstant *constant;
1062 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1063 ((GIrNode *)constant)->name = g_strdup (name);
1064 constant->value = g_strdup (branch);
1065 constant->type = union_->discriminator_type;
1066 constant->deprecated = FALSE;
1068 union_->discriminators = g_list_append (union_->discriminators, constant);
1070 state_switch (ctx, STATE_UNION_FIELD);
1074 g_assert_not_reached ();
1081 start_alias (GMarkupParseContext *context,
1082 const gchar *element_name,
1083 const gchar **attribute_names,
1084 const gchar **attribute_values,
1089 const gchar *target;
1093 name = find_attribute ("name", attribute_names, attribute_values);
1096 MISSING_ATTRIBUTE (context, error, element_name, "name");
1100 target = find_attribute ("target", attribute_names, attribute_values);
1103 MISSING_ATTRIBUTE (context, error, element_name, "target");
1107 value = g_strdup (target);
1108 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
1109 if (!strchr (target, '.'))
1111 const BasicTypeInfo *basic = parse_basic (target);
1115 /* For non-basic types, re-qualify the interface */
1116 value = g_strdup_printf ("%s.%s", ctx->namespace, target);
1119 g_hash_table_replace (ctx->aliases, key, value);
1125 start_enum (GMarkupParseContext *context,
1126 const gchar *element_name,
1127 const gchar **attribute_names,
1128 const gchar **attribute_values,
1132 if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
1133 (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))
1136 const gchar *typename;
1137 const gchar *typeinit;
1138 const gchar *deprecated;
1140 name = find_attribute ("name", attribute_names, attribute_values);
1141 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1142 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1143 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1146 MISSING_ATTRIBUTE (context, error, element_name, "name");
1151 if (strcmp (element_name, "enumeration") == 0)
1152 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM);
1154 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS);
1155 ((GIrNode *)enum_)->name = g_strdup (name);
1156 enum_->gtype_name = g_strdup (typename);
1157 enum_->gtype_init = g_strdup (typeinit);
1159 enum_->deprecated = TRUE;
1161 enum_->deprecated = FALSE;
1163 ctx->current_node = (GIrNode *) enum_;
1164 ctx->current_module->entries =
1165 g_list_append (ctx->current_module->entries, enum_);
1167 state_switch (ctx, STATE_ENUM);
1176 start_property (GMarkupParseContext *context,
1177 const gchar *element_name,
1178 const gchar **attribute_names,
1179 const gchar **attribute_values,
1183 if (strcmp (element_name, "property") == 0 &&
1184 (ctx->state == STATE_CLASS ||
1185 ctx->state == STATE_INTERFACE))
1188 const gchar *readable;
1189 const gchar *writable;
1190 const gchar *construct;
1191 const gchar *construct_only;
1193 name = find_attribute ("name", attribute_names, attribute_values);
1194 readable = find_attribute ("readable", attribute_names, attribute_values);
1195 writable = find_attribute ("writable", attribute_names, attribute_values);
1196 construct = find_attribute ("construct", attribute_names, attribute_values);
1197 construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
1200 MISSING_ATTRIBUTE (context, error, element_name, "name");
1203 GIrNodeProperty *property;
1204 GIrNodeInterface *iface;
1206 property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
1207 ctx->current_typed = (GIrNode*) property;
1209 ((GIrNode *)property)->name = g_strdup (name);
1211 /* Assume properties are readable */
1212 if (readable == NULL || strcmp (readable, "1") == 0)
1213 property->readable = TRUE;
1215 property->readable = FALSE;
1216 if (writable && strcmp (writable, "1") == 0)
1217 property->writable = TRUE;
1219 property->writable = FALSE;
1220 if (construct && strcmp (construct, "1") == 0)
1221 property->construct = TRUE;
1223 property->construct = FALSE;
1224 if (construct_only && strcmp (construct_only, "1") == 0)
1225 property->construct_only = TRUE;
1227 property->construct_only = FALSE;
1229 iface = (GIrNodeInterface *)ctx->current_node;
1230 iface->members = g_list_append (iface->members, property);
1232 if (ctx->state == STATE_CLASS)
1233 state_switch (ctx, STATE_CLASS_PROPERTY);
1234 else if (ctx->state == STATE_INTERFACE)
1235 state_switch (ctx, STATE_INTERFACE_PROPERTY);
1237 g_assert_not_reached ();
1246 parse_value (const gchar *str)
1250 /* FIXME just a quick hack */
1251 shift_op = strstr (str, "<<");
1257 base = strtol (str, NULL, 10);
1258 shift = strtol (shift_op + 3, NULL, 10);
1260 return base << shift;
1263 return strtol (str, NULL, 10);
1269 start_member (GMarkupParseContext *context,
1270 const gchar *element_name,
1271 const gchar **attribute_names,
1272 const gchar **attribute_values,
1276 if (strcmp (element_name, "member") == 0 &&
1277 ctx->state == STATE_ENUM)
1281 const gchar *deprecated;
1283 name = find_attribute ("name", attribute_names, attribute_values);
1284 value = find_attribute ("value", attribute_names, attribute_values);
1285 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1288 MISSING_ATTRIBUTE (context, error, element_name, "name");
1292 GIrNodeValue *value_;
1294 value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
1296 ((GIrNode *)value_)->name = g_strdup (name);
1298 value_->value = parse_value (value);
1301 value_->deprecated = TRUE;
1303 value_->deprecated = FALSE;
1305 enum_ = (GIrNodeEnum *)ctx->current_node;
1306 enum_->values = g_list_append (enum_->values, value_);
1315 start_constant (GMarkupParseContext *context,
1316 const gchar *element_name,
1317 const gchar **attribute_names,
1318 const gchar **attribute_values,
1322 if (strcmp (element_name, "constant") == 0 &&
1323 (ctx->state == STATE_NAMESPACE ||
1324 ctx->state == STATE_CLASS ||
1325 ctx->state == STATE_INTERFACE))
1329 const gchar *deprecated;
1331 name = find_attribute ("name", attribute_names, attribute_values);
1332 value = find_attribute ("value", attribute_names, attribute_values);
1333 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1336 MISSING_ATTRIBUTE (context, error, element_name, "name");
1337 else if (value == NULL)
1338 MISSING_ATTRIBUTE (context, error, element_name, "value");
1341 GIrNodeConstant *constant;
1343 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1345 ((GIrNode *)constant)->name = g_strdup (name);
1346 constant->value = g_strdup (value);
1348 ctx->current_typed = (GIrNode*) constant;
1351 constant->deprecated = TRUE;
1353 constant->deprecated = FALSE;
1355 if (ctx->state == STATE_NAMESPACE)
1357 ctx->current_node = (GIrNode *) constant;
1358 ctx->current_module->entries =
1359 g_list_append (ctx->current_module->entries, constant);
1363 GIrNodeInterface *iface;
1365 iface = (GIrNodeInterface *)ctx->current_node;
1366 iface->members = g_list_append (iface->members, constant);
1371 case STATE_NAMESPACE:
1372 state_switch (ctx, STATE_NAMESPACE_CONSTANT);
1375 state_switch (ctx, STATE_CLASS_CONSTANT);
1377 case STATE_INTERFACE:
1378 state_switch (ctx, STATE_INTERFACE_CONSTANT);
1381 g_assert_not_reached ();
1392 start_errordomain (GMarkupParseContext *context,
1393 const gchar *element_name,
1394 const gchar **attribute_names,
1395 const gchar **attribute_values,
1399 if (strcmp (element_name, "errordomain") == 0 &&
1400 ctx->state == STATE_NAMESPACE)
1403 const gchar *getquark;
1405 const gchar *deprecated;
1407 name = find_attribute ("name", attribute_names, attribute_values);
1408 getquark = find_attribute ("get-quark", attribute_names, attribute_values);
1409 codes = find_attribute ("codes", attribute_names, attribute_values);
1410 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1413 MISSING_ATTRIBUTE (context, error, element_name, "name");
1414 else if (getquark == NULL)
1415 MISSING_ATTRIBUTE (context, error, element_name, "getquark");
1416 else if (codes == NULL)
1417 MISSING_ATTRIBUTE (context, error, element_name, "codes");
1420 GIrNodeErrorDomain *domain;
1422 domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
1424 ((GIrNode *)domain)->name = g_strdup (name);
1425 domain->getquark = g_strdup (getquark);
1426 domain->codes = g_strdup (codes);
1429 domain->deprecated = TRUE;
1431 domain->deprecated = FALSE;
1433 ctx->current_node = (GIrNode *) domain;
1434 ctx->current_module->entries =
1435 g_list_append (ctx->current_module->entries, domain);
1437 state_switch (ctx, STATE_ERRORDOMAIN);
1446 start_interface (GMarkupParseContext *context,
1447 const gchar *element_name,
1448 const gchar **attribute_names,
1449 const gchar **attribute_values,
1453 if (strcmp (element_name, "interface") == 0 &&
1454 ctx->state == STATE_NAMESPACE)
1457 const gchar *typename;
1458 const gchar *typeinit;
1459 const gchar *deprecated;
1461 name = find_attribute ("name", attribute_names, attribute_values);
1462 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1463 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1464 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1467 MISSING_ATTRIBUTE (context, error, element_name, "name");
1468 else if (typename == NULL)
1469 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1470 else if (typeinit == NULL)
1471 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1474 GIrNodeInterface *iface;
1476 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE);
1477 ((GIrNode *)iface)->name = g_strdup (name);
1478 iface->gtype_name = g_strdup (typename);
1479 iface->gtype_init = g_strdup (typeinit);
1481 iface->deprecated = TRUE;
1483 iface->deprecated = FALSE;
1485 ctx->current_node = (GIrNode *) iface;
1486 ctx->current_module->entries =
1487 g_list_append (ctx->current_module->entries, iface);
1489 state_switch (ctx, STATE_INTERFACE);
1499 start_class (GMarkupParseContext *context,
1500 const gchar *element_name,
1501 const gchar **attribute_names,
1502 const gchar **attribute_values,
1506 if (strcmp (element_name, "class") == 0 &&
1507 ctx->state == STATE_NAMESPACE)
1510 const gchar *parent;
1511 const gchar *typename;
1512 const gchar *typeinit;
1513 const gchar *deprecated;
1514 const gchar *abstract;
1516 name = find_attribute ("name", attribute_names, attribute_values);
1517 parent = find_attribute ("parent", attribute_names, attribute_values);
1518 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1519 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1520 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1521 abstract = find_attribute ("abstract", attribute_names, attribute_values);
1524 MISSING_ATTRIBUTE (context, error, element_name, "name");
1525 else if (typename == NULL)
1526 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1527 else if (typeinit == NULL && strcmp (typename, "GObject"))
1528 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1531 GIrNodeInterface *iface;
1533 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT);
1534 ((GIrNode *)iface)->name = g_strdup (name);
1535 iface->gtype_name = g_strdup (typename);
1536 iface->gtype_init = g_strdup (typeinit);
1537 iface->parent = g_strdup (parent);
1539 iface->deprecated = TRUE;
1541 iface->deprecated = FALSE;
1543 iface->abstract = abstract && strcmp (abstract, "1") == 0;
1545 ctx->current_node = (GIrNode *) iface;
1546 ctx->current_module->entries =
1547 g_list_append (ctx->current_module->entries, iface);
1549 state_switch (ctx, STATE_CLASS);
1558 start_type (GMarkupParseContext *context,
1559 const gchar *element_name,
1560 const gchar **attribute_names,
1561 const gchar **attribute_values,
1568 gboolean is_varargs;
1569 GIrNodeType *typenode;
1571 is_array = strcmp (element_name, "array") == 0;
1572 is_varargs = strcmp (element_name, "varargs") == 0;
1574 if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
1577 if (ctx->state == STATE_TYPE)
1580 ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters);
1581 ctx->type_parameters = NULL;
1583 else if (ctx->state == STATE_FUNCTION_PARAMETER ||
1584 ctx->state == STATE_FUNCTION_RETURN ||
1585 ctx->state == STATE_STRUCT_FIELD ||
1586 ctx->state == STATE_UNION_FIELD ||
1587 ctx->state == STATE_CLASS_PROPERTY ||
1588 ctx->state == STATE_CLASS_FIELD ||
1589 ctx->state == STATE_INTERFACE_FIELD ||
1590 ctx->state == STATE_INTERFACE_PROPERTY ||
1591 ctx->state == STATE_BOXED_FIELD ||
1592 ctx->state == STATE_NAMESPACE_CONSTANT ||
1593 ctx->state == STATE_CLASS_CONSTANT ||
1594 ctx->state == STATE_INTERFACE_CONSTANT
1597 state_switch (ctx, STATE_TYPE);
1598 ctx->type_depth = 1;
1601 switch (ctx->current_node->type)
1603 case G_IR_NODE_FUNCTION:
1604 case G_IR_NODE_CALLBACK:
1606 GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
1607 func->is_varargs = TRUE;
1610 case G_IR_NODE_VFUNC:
1612 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
1613 vfunc->is_varargs = TRUE;
1616 /* list others individually rather than with default: so that compiler
1617 * warns if new node types are added without adding them to the switch
1619 case G_IR_NODE_INVALID:
1620 case G_IR_NODE_ENUM:
1621 case G_IR_NODE_FLAGS:
1622 case G_IR_NODE_CONSTANT:
1623 case G_IR_NODE_ERROR_DOMAIN:
1624 case G_IR_NODE_PARAM:
1625 case G_IR_NODE_TYPE:
1626 case G_IR_NODE_PROPERTY:
1627 case G_IR_NODE_SIGNAL:
1628 case G_IR_NODE_VALUE:
1629 case G_IR_NODE_FIELD:
1630 case G_IR_NODE_XREF:
1631 case G_IR_NODE_STRUCT:
1632 case G_IR_NODE_BOXED:
1633 case G_IR_NODE_OBJECT:
1634 case G_IR_NODE_INTERFACE:
1635 case G_IR_NODE_UNION:
1636 g_assert_not_reached ();
1640 ctx->type_stack = NULL;
1641 ctx->type_parameters = NULL;
1644 if (!ctx->current_typed)
1648 G_MARKUP_ERROR_INVALID_CONTENT,
1649 "The element <type> is invalid here");
1662 typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
1664 typenode->tag = GI_TYPE_TAG_ARRAY;
1665 typenode->is_pointer = TRUE;
1666 typenode->is_array = TRUE;
1668 zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
1669 len = find_attribute ("length", attribute_names, attribute_values);
1670 size = find_attribute ("fixed-size", attribute_names, attribute_values);
1672 typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0);
1673 typenode->has_length = len != NULL;
1674 typenode->length = typenode->has_length ? atoi (len) : -1;
1676 typenode->has_size = size != NULL;
1677 typenode->size = typenode->has_size ? atoi (size) : -1;
1682 name = find_attribute ("name", attribute_names, attribute_values);
1685 MISSING_ATTRIBUTE (context, error, element_name, "name");
1688 ctype = find_attribute ("c:type", attribute_names, attribute_values);
1691 const char *cp = ctype + strlen(ctype) - 1;
1692 while (cp > ctype && *cp-- == '*')
1696 if (ctx->current_typed->type == G_IR_NODE_PARAM &&
1697 ((GIrNodeParam *)ctx->current_typed)->out &&
1701 typenode = parse_type (ctx, name);
1703 /* A 'disguised' structure is one where the c:type is a typedef that
1704 * doesn't look like a pointer, but is internally.
1706 if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
1707 is_disguised_structure (ctx, typenode->interface))
1710 if (pointer_depth > 0)
1711 typenode->is_pointer = TRUE;
1714 ctx->type_parameters = g_list_append (ctx->type_parameters, typenode);
1720 end_type_top (ParseContext *ctx)
1722 GIrNodeType *typenode;
1724 if (!ctx->type_parameters)
1727 typenode = (GIrNodeType*)ctx->type_parameters->data;
1729 /* Default to pointer for unspecified containers */
1730 if (typenode->tag == GI_TYPE_TAG_ARRAY ||
1731 typenode->tag == GI_TYPE_TAG_GLIST ||
1732 typenode->tag == GI_TYPE_TAG_GSLIST)
1734 if (typenode->parameter_type1 == NULL)
1735 typenode->parameter_type1 = parse_type (ctx, "any");
1737 else if (typenode->tag == GI_TYPE_TAG_GHASH)
1739 if (typenode->parameter_type1 == NULL)
1741 typenode->parameter_type1 = parse_type (ctx, "any");
1742 typenode->parameter_type2 = parse_type (ctx, "any");
1746 switch (ctx->current_typed->type)
1748 case G_IR_NODE_PARAM:
1750 GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed;
1751 param->type = typenode;
1754 case G_IR_NODE_FIELD:
1756 GIrNodeField *field = (GIrNodeField *)ctx->current_typed;
1757 field->type = typenode;
1760 case G_IR_NODE_PROPERTY:
1762 GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed;
1763 property->type = typenode;
1766 case G_IR_NODE_CONSTANT:
1768 GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed;
1769 constant->type = typenode;
1773 g_printerr("current node is %d\n", ctx->current_node->type);
1774 g_assert_not_reached ();
1776 g_list_free (ctx->type_parameters);
1779 ctx->type_depth = 0;
1780 ctx->type_parameters = NULL;
1781 ctx->current_typed = NULL;
1785 end_type_recurse (ParseContext *ctx)
1787 GIrNodeType *parent;
1788 GIrNodeType *param = NULL;
1790 parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data;
1791 if (ctx->type_parameters)
1792 param = (GIrNodeType *) ctx->type_parameters->data;
1794 if (parent->tag == GI_TYPE_TAG_ARRAY ||
1795 parent->tag == GI_TYPE_TAG_GLIST ||
1796 parent->tag == GI_TYPE_TAG_GSLIST)
1798 g_assert (param != NULL);
1800 if (parent->parameter_type1 == NULL)
1801 parent->parameter_type1 = param;
1803 g_assert_not_reached ();
1805 else if (parent->tag == GI_TYPE_TAG_GHASH)
1807 g_assert (param != NULL);
1809 if (parent->parameter_type1 == NULL)
1810 parent->parameter_type1 = param;
1811 else if (parent->parameter_type2 == NULL)
1812 parent->parameter_type2 = param;
1814 g_assert_not_reached ();
1816 g_list_free (ctx->type_parameters);
1817 ctx->type_parameters = (GList *)ctx->type_stack->data;
1818 ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
1822 end_type (ParseContext *ctx)
1824 if (ctx->type_depth == 1)
1827 state_switch (ctx, ctx->prev_state);
1831 end_type_recurse (ctx);
1837 start_return_value (GMarkupParseContext *context,
1838 const gchar *element_name,
1839 const gchar **attribute_names,
1840 const gchar **attribute_values,
1844 if (strcmp (element_name, "return-value") == 0 &&
1845 ctx->state == STATE_FUNCTION)
1847 GIrNodeParam *param;
1848 const gchar *transfer;
1850 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
1853 param->retval = TRUE;
1855 ctx->current_typed = (GIrNode*) param;
1857 state_switch (ctx, STATE_FUNCTION_RETURN);
1859 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1860 parse_param_transfer (param, transfer);
1862 switch (ctx->current_node->type)
1864 case G_IR_NODE_FUNCTION:
1865 case G_IR_NODE_CALLBACK:
1867 GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node;
1868 func->result = param;
1871 case G_IR_NODE_SIGNAL:
1873 GIrNodeSignal *signal = (GIrNodeSignal *)ctx->current_node;
1874 signal->result = param;
1877 case G_IR_NODE_VFUNC:
1879 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node;
1880 vfunc->result = param;
1884 g_assert_not_reached ();
1894 start_implements (GMarkupParseContext *context,
1895 const gchar *element_name,
1896 const gchar **attribute_names,
1897 const gchar **attribute_values,
1901 GIrNodeInterface *iface;
1904 if (strcmp (element_name, "implements") != 0 ||
1905 !(ctx->state == STATE_CLASS))
1908 state_switch (ctx, STATE_IMPLEMENTS);
1910 name = find_attribute ("name", attribute_names, attribute_values);
1913 MISSING_ATTRIBUTE (context, error, element_name, "name");
1917 iface = (GIrNodeInterface *)ctx->current_node;
1918 iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
1924 start_glib_signal (GMarkupParseContext *context,
1925 const gchar *element_name,
1926 const gchar **attribute_names,
1927 const gchar **attribute_values,
1931 if (strcmp (element_name, "glib:signal") == 0 &&
1932 (ctx->state == STATE_CLASS ||
1933 ctx->state == STATE_INTERFACE))
1937 const gchar *no_recurse;
1938 const gchar *detailed;
1939 const gchar *action;
1940 const gchar *no_hooks;
1941 const gchar *has_class_closure;
1943 name = find_attribute ("name", attribute_names, attribute_values);
1944 when = find_attribute ("when", attribute_names, attribute_values);
1945 no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values);
1946 detailed = find_attribute ("detailed", attribute_names, attribute_values);
1947 action = find_attribute ("action", attribute_names, attribute_values);
1948 no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values);
1949 has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values);
1952 MISSING_ATTRIBUTE (context, error, element_name, "name");
1955 GIrNodeInterface *iface;
1956 GIrNodeSignal *signal;
1958 signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
1960 ((GIrNode *)signal)->name = g_strdup (name);
1962 signal->run_first = FALSE;
1963 signal->run_last = FALSE;
1964 signal->run_cleanup = FALSE;
1965 if (when == NULL || strcmp (when, "LAST") == 0)
1966 signal->run_last = TRUE;
1967 else if (strcmp (when, "FIRST") == 0)
1968 signal->run_first = TRUE;
1970 signal->run_cleanup = TRUE;
1972 if (no_recurse && strcmp (no_recurse, "1") == 0)
1973 signal->no_recurse = TRUE;
1975 signal->no_recurse = FALSE;
1976 if (detailed && strcmp (detailed, "1") == 0)
1977 signal->detailed = TRUE;
1979 signal->detailed = FALSE;
1980 if (action && strcmp (action, "1") == 0)
1981 signal->action = TRUE;
1983 signal->action = FALSE;
1984 if (no_hooks && strcmp (no_hooks, "1") == 0)
1985 signal->no_hooks = TRUE;
1987 signal->no_hooks = FALSE;
1988 if (has_class_closure && strcmp (has_class_closure, "1") == 0)
1989 signal->has_class_closure = TRUE;
1991 signal->has_class_closure = FALSE;
1993 iface = (GIrNodeInterface *)ctx->current_node;
1994 iface->members = g_list_append (iface->members, signal);
1996 ctx->current_node = (GIrNode *)signal;
1997 state_switch (ctx, STATE_FUNCTION);
2006 start_vfunc (GMarkupParseContext *context,
2007 const gchar *element_name,
2008 const gchar **attribute_names,
2009 const gchar **attribute_values,
2013 if (strcmp (element_name, "vfunc") == 0 &&
2014 (ctx->state == STATE_CLASS ||
2015 ctx->state == STATE_INTERFACE))
2018 const gchar *must_chain_up;
2019 const gchar *override;
2020 const gchar *is_class_closure;
2021 const gchar *offset;
2023 name = find_attribute ("name", attribute_names, attribute_values);
2024 must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values);
2025 override = find_attribute ("override", attribute_names, attribute_values);
2026 is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values);
2027 offset = find_attribute ("offset", attribute_names, attribute_values);
2030 MISSING_ATTRIBUTE (context, error, element_name, "name");
2033 GIrNodeInterface *iface;
2034 GIrNodeVFunc *vfunc;
2036 vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
2038 ((GIrNode *)vfunc)->name = g_strdup (name);
2040 if (must_chain_up && strcmp (must_chain_up, "1") == 0)
2041 vfunc->must_chain_up = TRUE;
2043 vfunc->must_chain_up = FALSE;
2045 if (override && strcmp (override, "always") == 0)
2047 vfunc->must_be_implemented = TRUE;
2048 vfunc->must_not_be_implemented = FALSE;
2050 else if (override && strcmp (override, "never") == 0)
2052 vfunc->must_be_implemented = FALSE;
2053 vfunc->must_not_be_implemented = TRUE;
2057 vfunc->must_be_implemented = FALSE;
2058 vfunc->must_not_be_implemented = FALSE;
2061 if (is_class_closure && strcmp (is_class_closure, "1") == 0)
2062 vfunc->is_class_closure = TRUE;
2064 vfunc->is_class_closure = FALSE;
2067 vfunc->offset = atoi (offset);
2071 iface = (GIrNodeInterface *)ctx->current_node;
2072 iface->members = g_list_append (iface->members, vfunc);
2074 ctx->current_node = (GIrNode *)vfunc;
2075 state_switch (ctx, STATE_FUNCTION);
2085 start_struct (GMarkupParseContext *context,
2086 const gchar *element_name,
2087 const gchar **attribute_names,
2088 const gchar **attribute_values,
2092 if (strcmp (element_name, "record") == 0 &&
2093 ctx->state == STATE_NAMESPACE)
2096 const gchar *deprecated;
2097 const gchar *disguised;
2098 const gchar *gtype_name;
2099 const gchar *gtype_init;
2100 GIrNodeStruct *struct_;
2102 name = find_attribute ("name", attribute_names, attribute_values);
2103 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2104 disguised = find_attribute ("disguised", attribute_names, attribute_values);
2105 gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
2106 gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
2110 MISSING_ATTRIBUTE (context, error, element_name, "name");
2113 if ((gtype_name == NULL && gtype_init != NULL))
2115 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
2118 if ((gtype_name != NULL && gtype_init == NULL))
2120 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
2124 struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
2126 ((GIrNode *)struct_)->name = g_strdup (name);
2128 struct_->deprecated = TRUE;
2130 struct_->deprecated = FALSE;
2132 if (disguised && strcmp (disguised, "1") == 0)
2133 struct_->disguised = TRUE;
2135 struct_->gtype_name = g_strdup (gtype_name);
2136 struct_->gtype_init = g_strdup (gtype_init);
2138 ctx->current_node = (GIrNode *)struct_;
2139 ctx->current_module->entries =
2140 g_list_append (ctx->current_module->entries, struct_);
2142 state_switch (ctx, STATE_STRUCT);
2150 start_union (GMarkupParseContext *context,
2151 const gchar *element_name,
2152 const gchar **attribute_names,
2153 const gchar **attribute_values,
2157 if (strcmp (element_name, "union") == 0 &&
2158 ctx->state == STATE_NAMESPACE)
2161 const gchar *deprecated;
2162 const gchar *typename;
2163 const gchar *typeinit;
2165 name = find_attribute ("name", attribute_names, attribute_values);
2166 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2167 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
2168 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
2171 MISSING_ATTRIBUTE (context, error, element_name, "name");
2174 GIrNodeUnion *union_;
2176 union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
2178 ((GIrNode *)union_)->name = g_strdup (name);
2179 union_->gtype_name = g_strdup (typename);
2180 union_->gtype_init = g_strdup (typeinit);
2182 union_->deprecated = TRUE;
2184 union_->deprecated = FALSE;
2186 ctx->current_node = (GIrNode *)union_;
2187 ctx->current_module->entries =
2188 g_list_append (ctx->current_module->entries, union_);
2190 state_switch (ctx, STATE_UNION);
2198 start_discriminator (GMarkupParseContext *context,
2199 const gchar *element_name,
2200 const gchar **attribute_names,
2201 const gchar **attribute_values,
2205 if (strcmp (element_name, "discriminator") == 0 &&
2206 ctx->state == STATE_UNION)
2209 const gchar *offset;
2211 type = find_attribute ("type", attribute_names, attribute_values);
2212 offset = find_attribute ("offset", attribute_names, attribute_values);
2214 MISSING_ATTRIBUTE (context, error, element_name, "type");
2215 else if (offset == NULL)
2216 MISSING_ATTRIBUTE (context, error, element_name, "offset");
2218 ((GIrNodeUnion *)ctx->current_node)->discriminator_type
2219 = parse_type (ctx, type);
2220 ((GIrNodeUnion *)ctx->current_node)->discriminator_offset
2231 parse_include (GMarkupParseContext *context,
2234 const char *version,
2240 gboolean success = FALSE;
2244 for (l = ctx->parser->parsed_modules; l; l = l->next)
2246 GIrModule *m = l->data;
2248 if (strcmp (m->name, name) == 0)
2250 if (strcmp (m->version, version) == 0)
2252 ctx->include_modules = g_list_prepend (ctx->include_modules, m);
2260 G_MARKUP_ERROR_INVALID_CONTENT,
2261 "Module '%s' imported with conflicting versions '%s' and '%s'",
2262 name, m->version, version);
2268 girpath = locate_gir (ctx->parser, name, version);
2270 if (girpath == NULL)
2274 G_MARKUP_ERROR_INVALID_CONTENT,
2275 "Could not find GIR file '%s.gir'; check XDG_DATA_DIRS or use --includedir",
2280 g_debug ("Parsing include %s", girpath);
2282 if (!g_file_get_contents (girpath, &buffer, &length, error))
2289 modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error);
2290 success = error != NULL;
2292 ctx->include_modules = g_list_concat (ctx->include_modules,
2300 extern GLogLevelFlags logged_levels;
2303 start_element_handler (GMarkupParseContext *context,
2304 const gchar *element_name,
2305 const gchar **attribute_names,
2306 const gchar **attribute_values,
2310 ParseContext *ctx = user_data;
2311 gint line_number, char_number;
2313 if (logged_levels & G_LOG_LEVEL_DEBUG)
2315 GString *tags = g_string_new ("");
2317 for (i = 0; attribute_names[i]; i++)
2318 g_string_append_printf (tags, "%s=\"%s\" ",
2320 attribute_values[i]);
2324 g_string_insert_c (tags, 0, ' ');
2325 g_string_truncate (tags, tags->len - 1);
2327 g_debug ("<%s%s>", element_name, tags->str);
2328 g_string_free (tags, TRUE);
2331 switch (element_name[0])
2334 if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0)
2336 state_switch (ctx, STATE_ALIAS);
2339 if (start_type (context, element_name,
2340 attribute_names, attribute_values,
2345 if (start_enum (context, element_name,
2346 attribute_names, attribute_values,
2351 if (start_function (context, element_name,
2352 attribute_names, attribute_values,
2355 else if (start_constant (context, element_name,
2356 attribute_names, attribute_values,
2359 else if (start_class (context, element_name,
2360 attribute_names, attribute_values,
2366 if (start_discriminator (context, element_name,
2367 attribute_names, attribute_values,
2373 if (start_enum (context, element_name,
2374 attribute_names, attribute_values,
2377 else if (start_errordomain (context, element_name,
2378 attribute_names, attribute_values,
2384 if (start_function (context, element_name,
2385 attribute_names, attribute_values,
2388 else if (start_field (context, element_name,
2389 attribute_names, attribute_values,
2395 if (start_glib_boxed (context, element_name,
2396 attribute_names, attribute_values,
2399 else if (start_glib_signal (context, element_name,
2400 attribute_names, attribute_values,
2406 if (strcmp (element_name, "include") == 0 &&
2407 ctx->state == STATE_REPOSITORY)
2410 const gchar *version;
2412 name = find_attribute ("name", attribute_names, attribute_values);
2413 version = find_attribute ("version", attribute_names, attribute_values);
2417 MISSING_ATTRIBUTE (context, error, element_name, "name");
2420 if (version == NULL)
2422 MISSING_ATTRIBUTE (context, error, element_name, "version");
2426 if (!parse_include (context, ctx, name, version, error))
2429 ctx->dependencies = g_list_prepend (ctx->dependencies,
2430 g_strdup_printf ("%s-%s", name, version));
2433 state_switch (ctx, STATE_INCLUDE);
2436 if (start_interface (context, element_name,
2437 attribute_names, attribute_values,
2440 else if (start_implements (context, element_name,
2441 attribute_names, attribute_values,
2447 if (start_function (context, element_name,
2448 attribute_names, attribute_values,
2451 else if (start_member (context, element_name,
2452 attribute_names, attribute_values,
2458 if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2460 const gchar *name, *version, *shared_library;
2462 if (ctx->current_module != NULL)
2466 G_MARKUP_ERROR_INVALID_CONTENT,
2467 "Only one <namespace/> element is currently allowed per <repository/>");
2471 name = find_attribute ("name", attribute_names, attribute_values);
2472 version = find_attribute ("version", attribute_names, attribute_values);
2473 shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2476 MISSING_ATTRIBUTE (context, error, element_name, "name");
2477 else if (version == NULL)
2478 MISSING_ATTRIBUTE (context, error, element_name, "version");
2483 if (strcmp (name, ctx->namespace) != 0)
2486 G_MARKUP_ERROR_INVALID_CONTENT,
2487 "<namespace/> name element '%s' doesn't match file name '%s'",
2488 name, ctx->namespace);
2490 ctx->current_module = g_ir_module_new (name, version, shared_library);
2492 ctx->current_module->aliases = ctx->aliases;
2493 ctx->aliases = NULL;
2494 ctx->current_module->disguised_structures = ctx->disguised_structures;
2495 ctx->disguised_structures = NULL;
2497 for (l = ctx->include_modules; l; l = l->next)
2498 g_ir_module_add_include_module (ctx->current_module, l->data);
2500 g_list_free (ctx->include_modules);
2501 ctx->include_modules = NULL;
2503 ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2504 ctx->current_module->dependencies = ctx->dependencies;
2506 state_switch (ctx, STATE_NAMESPACE);
2513 if (start_property (context, element_name,
2514 attribute_names, attribute_values,
2517 else if (strcmp (element_name, "parameters") == 0 &&
2518 ctx->state == STATE_FUNCTION)
2520 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2524 else if (start_parameter (context, element_name,
2525 attribute_names, attribute_values,
2528 else if (strcmp (element_name, "prerequisite") == 0 &&
2529 ctx->state == STATE_INTERFACE)
2533 name = find_attribute ("name", attribute_names, attribute_values);
2535 state_switch (ctx, STATE_PREREQUISITE);
2538 MISSING_ATTRIBUTE (context, error, element_name, "name");
2541 GIrNodeInterface *iface;
2543 iface = (GIrNodeInterface *)ctx->current_node;
2544 iface->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
2551 if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
2553 const gchar *version;
2555 version = find_attribute ("version", attribute_names, attribute_values);
2557 if (version == NULL)
2558 MISSING_ATTRIBUTE (context, error, element_name, "version");
2559 else if (strcmp (version, "1.0") != 0)
2562 G_MARKUP_ERROR_INVALID_CONTENT,
2563 "Unsupported version '%s'",
2566 state_switch (ctx, STATE_REPOSITORY);
2570 else if (start_return_value (context, element_name,
2571 attribute_names, attribute_values,
2574 else if (start_struct (context, element_name,
2575 attribute_names, attribute_values,
2581 if (start_union (context, element_name,
2582 attribute_names, attribute_values,
2588 if (start_type (context, element_name,
2589 attribute_names, attribute_values,
2595 if (start_vfunc (context, element_name,
2596 attribute_names, attribute_values,
2599 if (start_type (context, element_name,
2600 attribute_names, attribute_values,
2606 g_markup_parse_context_get_position (context, &line_number, &char_number);
2608 if (error && *error == NULL)
2611 G_MARKUP_ERROR_UNKNOWN_ELEMENT,
2612 "Unexpected start tag '%s' on line %d char %d; current state=%d",
2614 line_number, char_number, ctx->state);
2619 g_markup_parse_context_get_position (context, &line_number, &char_number);
2621 fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message);
2622 backtrace_stderr ();
2627 require_one_of_end_elements (GMarkupParseContext *context,
2629 const char *actual_name,
2634 int line_number, char_number;
2635 const char *expected;
2636 gboolean matched = FALSE;
2638 va_start (args, error);
2640 while ((expected = va_arg (args, const char*)) != NULL)
2642 if (strcmp (expected, actual_name) == 0)
2654 g_markup_parse_context_get_position (context, &line_number, &char_number);
2657 G_MARKUP_ERROR_INVALID_CONTENT,
2658 "Unexpected end tag '%s' on line %d char %d; current state=%d",
2660 line_number, char_number, ctx->state);
2666 require_end_element (GMarkupParseContext *context,
2668 const char *expected_name,
2669 const char *actual_name,
2672 return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
2676 end_element_handler (GMarkupParseContext *context,
2677 const gchar *element_name,
2681 ParseContext *ctx = user_data;
2683 g_debug ("</%s>", element_name);
2689 /* no need to GError here, GMarkup already catches this */
2692 case STATE_REPOSITORY:
2693 state_switch (ctx, STATE_END);
2697 if (require_end_element (context, ctx, "include", element_name, error))
2699 state_switch (ctx, STATE_REPOSITORY);
2703 case STATE_NAMESPACE:
2704 if (require_end_element (context, ctx, "namespace", element_name, error))
2706 ctx->current_module = NULL;
2707 state_switch (ctx, STATE_REPOSITORY);
2712 if (require_end_element (context, ctx, "alias", element_name, error))
2714 state_switch (ctx, STATE_NAMESPACE);
2718 case STATE_FUNCTION_RETURN:
2719 if (strcmp ("type", element_name) == 0)
2721 if (require_end_element (context, ctx, "return-value", element_name, error))
2723 state_switch (ctx, STATE_FUNCTION);
2727 case STATE_FUNCTION_PARAMETERS:
2728 if (require_end_element (context, ctx, "parameters", element_name, error))
2730 state_switch (ctx, STATE_FUNCTION);
2734 case STATE_FUNCTION_PARAMETER:
2735 if (strcmp ("type", element_name) == 0)
2737 if (require_end_element (context, ctx, "parameter", element_name, error))
2739 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2743 case STATE_FUNCTION:
2745 gboolean current_is_toplevel;
2746 GList *last = g_list_last (ctx->current_module->entries);
2748 current_is_toplevel = ctx->current_node == last->data;
2750 if (current_is_toplevel)
2752 ctx->current_node = NULL;
2753 state_switch (ctx, STATE_NAMESPACE);
2757 ctx->current_node = g_list_last (ctx->current_module->entries)->data;
2758 if (ctx->current_node->type == G_IR_NODE_INTERFACE)
2759 state_switch (ctx, STATE_INTERFACE);
2760 else if (ctx->current_node->type == G_IR_NODE_OBJECT)
2761 state_switch (ctx, STATE_CLASS);
2762 else if (ctx->current_node->type == G_IR_NODE_BOXED)
2763 state_switch (ctx, STATE_BOXED);
2764 else if (ctx->current_node->type == G_IR_NODE_STRUCT)
2765 state_switch (ctx, STATE_STRUCT);
2766 else if (ctx->current_node->type == G_IR_NODE_UNION)
2767 state_switch (ctx, STATE_UNION);
2770 int line_number, char_number;
2771 g_markup_parse_context_get_position (context, &line_number, &char_number);
2774 G_MARKUP_ERROR_INVALID_CONTENT,
2775 "Unexpected end tag '%s' on line %d char %d",
2777 line_number, char_number);
2783 case STATE_CLASS_FIELD:
2784 if (strcmp ("type", element_name) == 0)
2786 if (require_end_element (context, ctx, "field", element_name, error))
2788 state_switch (ctx, STATE_CLASS);
2792 case STATE_CLASS_PROPERTY:
2793 if (strcmp ("type", element_name) == 0)
2795 if (require_end_element (context, ctx, "property", element_name, error))
2797 state_switch (ctx, STATE_CLASS);
2802 if (require_end_element (context, ctx, "class", element_name, error))
2804 ctx->current_node = NULL;
2805 state_switch (ctx, STATE_NAMESPACE);
2809 case STATE_ERRORDOMAIN:
2810 if (require_end_element (context, ctx, "errordomain", element_name, error))
2812 ctx->current_node = NULL;
2813 state_switch (ctx, STATE_NAMESPACE);
2817 case STATE_INTERFACE_PROPERTY:
2818 if (strcmp ("type", element_name) == 0)
2820 if (require_end_element (context, ctx, "property", element_name, error))
2822 state_switch (ctx, STATE_INTERFACE);
2826 case STATE_INTERFACE_FIELD:
2827 if (strcmp ("type", element_name) == 0)
2829 if (require_end_element (context, ctx, "field", element_name, error))
2831 state_switch (ctx, STATE_INTERFACE);
2835 case STATE_INTERFACE:
2836 if (require_end_element (context, ctx, "interface", element_name, error))
2838 ctx->current_node = NULL;
2839 state_switch (ctx, STATE_NAMESPACE);
2844 if (strcmp ("member", element_name) == 0)
2846 else if (require_one_of_end_elements (context, ctx,
2847 element_name, error, "enumeration",
2850 ctx->current_node = NULL;
2851 state_switch (ctx, STATE_NAMESPACE);
2856 if (require_end_element (context, ctx, "glib:boxed", element_name, error))
2858 ctx->current_node = NULL;
2859 state_switch (ctx, STATE_NAMESPACE);
2863 case STATE_BOXED_FIELD:
2864 if (strcmp ("type", element_name) == 0)
2866 if (require_end_element (context, ctx, "field", element_name, error))
2868 state_switch (ctx, STATE_BOXED);
2872 case STATE_STRUCT_FIELD:
2873 if (strcmp ("type", element_name) == 0)
2875 if (require_end_element (context, ctx, "field", element_name, error))
2877 state_switch (ctx, STATE_STRUCT);
2882 if (require_end_element (context, ctx, "record", element_name, error))
2884 ctx->current_node = NULL;
2885 state_switch (ctx, STATE_NAMESPACE);
2889 case STATE_UNION_FIELD:
2890 if (strcmp ("type", element_name) == 0)
2892 if (require_end_element (context, ctx, "field", element_name, error))
2894 state_switch (ctx, STATE_UNION);
2899 if (require_end_element (context, ctx, "union", element_name, error))
2901 ctx->current_node = NULL;
2902 state_switch (ctx, STATE_NAMESPACE);
2905 case STATE_IMPLEMENTS:
2906 if (strcmp ("interface", element_name) == 0)
2908 if (require_end_element (context, ctx, "implements", element_name, error))
2909 state_switch (ctx, STATE_CLASS);
2911 case STATE_PREREQUISITE:
2912 if (require_end_element (context, ctx, "prerequisite", element_name, error))
2913 state_switch (ctx, STATE_INTERFACE);
2915 case STATE_NAMESPACE_CONSTANT:
2916 case STATE_CLASS_CONSTANT:
2917 case STATE_INTERFACE_CONSTANT:
2918 if (strcmp ("type", element_name) == 0)
2920 if (require_end_element (context, ctx, "constant", element_name, error))
2922 ctx->current_node = NULL;
2925 case STATE_NAMESPACE_CONSTANT:
2926 state_switch (ctx, STATE_NAMESPACE);
2928 case STATE_CLASS_CONSTANT:
2929 state_switch (ctx, STATE_CLASS);
2931 case STATE_INTERFACE_CONSTANT:
2932 state_switch (ctx, STATE_INTERFACE);
2935 g_assert_not_reached ();
2941 if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
2942 (strcmp ("varargs", element_name) == 0))
2948 g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
2953 text_handler (GMarkupParseContext *context,
2959 /* FIXME warn about non-whitespace text */
2963 cleanup (GMarkupParseContext *context,
2967 ParseContext *ctx = user_data;
2970 for (m = ctx->modules; m; m = m->next)
2971 g_ir_module_free (m->data);
2972 g_list_free (ctx->modules);
2973 ctx->modules = NULL;
2975 ctx->current_module = NULL;
2979 post_filter_varargs_functions (GList *list)
2987 GIrNode *node = iter->data;
2991 if (node->type == G_IR_NODE_FUNCTION)
2993 if (((GIrNodeFunction*)node)->is_varargs)
2995 list = g_list_delete_link (list, link);
3003 post_filter (GIrModule *module)
3007 module->entries = post_filter_varargs_functions (module->entries);
3008 iter = module->entries;
3011 GIrNode *node = iter->data;
3015 if (node->type == G_IR_NODE_OBJECT ||
3016 node->type == G_IR_NODE_INTERFACE)
3018 GIrNodeInterface *iface = (GIrNodeInterface*)node;
3019 iface->members = post_filter_varargs_functions (iface->members);
3021 else if (node->type == G_IR_NODE_BOXED)
3023 GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
3024 boxed->members = post_filter_varargs_functions (boxed->members);
3026 else if (node->type == G_IR_NODE_STRUCT)
3028 GIrNodeStruct *iface = (GIrNodeStruct*)node;
3029 iface->members = post_filter_varargs_functions (iface->members);
3031 else if (node->type == G_IR_NODE_UNION)
3033 GIrNodeUnion *iface = (GIrNodeUnion*)node;
3034 iface->members = post_filter_varargs_functions (iface->members);
3040 * g_ir_parser_parse_string:
3041 * @parser: a #GIrParser
3042 * @error: return location for a #GError, or %NULL
3044 * Parse a string that holds a complete GIR XML file, and return a list of a
3045 * a #GirModule for each <namespace/> element within the file.
3047 * @returns: a newly allocated list of #GIrModule. The modules themselves
3048 * are owned by the #GIrParser and will be freed along with the parser.
3051 g_ir_parser_parse_string (GIrParser *parser,
3052 const gchar *namespace,
3053 const gchar *buffer,
3057 ParseContext ctx = { 0 };
3058 GMarkupParseContext *context;
3060 ctx.parser = parser;
3061 ctx.state = STATE_START;
3062 ctx.namespace = namespace;
3063 ctx.include_modules = NULL;
3064 ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
3065 ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
3067 ctx.dependencies = NULL;
3068 ctx.current_module = NULL;
3070 context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
3072 if (!g_markup_parse_context_parse (context, buffer, length, error))
3075 if (!g_markup_parse_context_end_parse (context, error))
3078 g_markup_parse_context_free (context);
3080 context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL);
3081 if (!g_markup_parse_context_parse (context, buffer, length, error))
3084 if (!g_markup_parse_context_end_parse (context, error))
3087 parser->parsed_modules = g_list_concat (g_list_copy (ctx.modules),
3088 parser->parsed_modules);
3092 if (ctx.modules == NULL)
3094 /* An error occurred before we created a module, so we haven't
3095 * transferred ownership of these hash tables to the module.
3097 if (ctx.aliases != NULL)
3098 g_hash_table_destroy (ctx.aliases);
3099 if (ctx.disguised_structures != NULL)
3100 g_hash_table_destroy (ctx.disguised_structures);
3101 g_list_free (ctx.include_modules);
3104 g_markup_parse_context_free (context);
3110 * g_ir_parser_parse_file:
3111 * @parser: a #GIrParser
3112 * @error: return location for a #GError, or %NULL
3114 * Parse GIR XML file, and return a list of a a #GirModule for each
3115 * <namespace/> element within the file.
3117 * @returns: a newly allocated list of #GIrModule. The modules themselves
3118 * are owned by the #GIrParser and will be freed along with the parser.
3121 g_ir_parser_parse_file (GIrParser *parser,
3122 const gchar *filename,
3133 if (!g_str_has_suffix (filename, ".gir"))
3137 G_MARKUP_ERROR_INVALID_CONTENT,
3138 "Expected filename to end with '.gir'");
3142 g_debug ("[parsing] filename %s", filename);
3144 slash = g_strrstr (filename, "/");
3146 namespace = g_strdup (filename);
3148 namespace = g_strdup (slash+1);
3149 namespace[strlen(namespace)-4] = '\0';
3151 /* Remove version */
3152 dash = strstr (namespace, "-");
3156 if (!g_file_get_contents (filename, &buffer, &length, error))
3159 modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error);
3161 for (iter = modules; iter; iter = iter->next)
3163 post_filter ((GIrModule*)iter->data);