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 */
44 STATE_NAMESPACE, /* 5 */
48 STATE_FUNCTION_RETURN,
49 STATE_FUNCTION_PARAMETERS, /* 10 */
50 STATE_FUNCTION_PARAMETER,
54 STATE_INTERFACE, /* 15 */
55 STATE_INTERFACE_PROPERTY,
56 STATE_INTERFACE_FIELD,
66 STATE_NAMESPACE_CONSTANT,
68 STATE_INTERFACE_CONSTANT,
75 typedef struct _ParseContext ParseContext;
82 ParseState prev_state;
85 GList *include_modules;
88 GHashTable *disguised_structures;
90 const char *namespace;
91 GIrModule *current_module;
93 GIrNode *current_typed;
96 GList *type_parameters;
99 #define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
101 static void start_element_handler (GMarkupParseContext *context,
102 const gchar *element_name,
103 const gchar **attribute_names,
104 const gchar **attribute_values,
107 static void end_element_handler (GMarkupParseContext *context,
108 const gchar *element_name,
111 static void text_handler (GMarkupParseContext *context,
116 static void cleanup (GMarkupParseContext *context,
120 static GMarkupParser markup_parser =
122 start_element_handler,
130 start_alias (GMarkupParseContext *context,
131 const gchar *element_name,
132 const gchar **attribute_names,
133 const gchar **attribute_values,
137 static const gchar *find_attribute (const gchar *name,
138 const gchar **attribute_names,
139 const gchar **attribute_values);
143 g_ir_parser_new (void)
145 GIrParser *parser = g_slice_new0 (GIrParser);
151 g_ir_parser_free (GIrParser *parser)
155 if (parser->includes)
156 g_strfreev (parser->includes);
158 for (l = parser->parsed_modules; l; l = l->next)
159 g_ir_module_free (l->data);
161 g_slice_free (GIrParser, parser);
165 g_ir_parser_set_includes (GIrParser *parser,
166 const gchar *const *includes)
168 if (parser->includes)
169 g_strfreev (parser->includes);
171 parser->includes = g_strdupv ((char **)includes);
175 firstpass_start_element_handler (GMarkupParseContext *context,
176 const gchar *element_name,
177 const gchar **attribute_names,
178 const gchar **attribute_values,
182 ParseContext *ctx = user_data;
184 if (strcmp (element_name, "alias") == 0)
186 start_alias (context, element_name, attribute_names, attribute_values,
189 else if (strcmp (element_name, "record") == 0)
192 const gchar *disguised;
194 name = find_attribute ("name", attribute_names, attribute_values);
195 disguised = find_attribute ("disguised", attribute_names, attribute_values);
197 if (disguised && strcmp (disguised, "1") == 0)
201 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
202 g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
208 firstpass_end_element_handler (GMarkupParseContext *context,
209 const gchar *element_name,
215 static GMarkupParser firstpass_parser =
217 firstpass_start_element_handler,
218 firstpass_end_element_handler,
225 locate_gir (GIrParser *parser,
229 const gchar *const *datadirs;
230 const gchar *const *dir;
234 datadirs = g_get_system_data_dirs ();
236 girname = g_strdup_printf ("%s-%s.gir", name, version);
238 if (parser->includes != NULL)
240 for (dir = (const gchar *const *)parser->includes; *dir; dir++)
242 path = g_build_filename (*dir, girname, NULL);
243 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
249 for (dir = datadirs; *dir; dir++)
251 path = g_build_filename (*dir, "gir-1.0", girname, NULL);
252 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
261 #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \
263 int line_number, char_number; \
264 g_markup_parse_context_get_position (context, &line_number, &char_number); \
265 g_set_error (error, \
267 G_MARKUP_ERROR_INVALID_CONTENT, \
268 "Line %d, character %d: The attribute '%s' on the element '%s' must be specified", \
269 line_number, char_number, attribute, element); \
273 backtrace_stderr (void)
275 #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
281 size = backtrace (array, 50);
282 strings = (char**) backtrace_symbols (array, size);
284 fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size);
286 for (i = 0; i < size; i++)
287 fprintf (stderr, "%s\n", strings[i]);
289 fprintf (stderr, "--- END BACKTRACE ---\n", size);
297 find_attribute (const gchar *name,
298 const gchar **attribute_names,
299 const gchar **attribute_values)
303 for (i = 0; attribute_names[i] != NULL; i++)
304 if (strcmp (attribute_names[i], name) == 0)
305 return attribute_values[i];
311 state_switch (ParseContext *ctx, ParseState newstate)
313 g_debug ("State: %d", newstate);
314 ctx->prev_state = ctx->state;
315 ctx->state = newstate;
319 pop_node (ParseContext *ctx)
321 g_assert (ctx->node_stack != 0);
323 GSList *top = ctx->node_stack;
324 GIrNode *node = top->data;
326 g_debug ("popping node %d %s", node->type, node->name);
327 ctx->node_stack = top->next;
328 g_slist_free_1 (top);
333 push_node (ParseContext *ctx, GIrNode *node)
335 g_debug ("pushing node %d %s", node->type, node->name);
336 ctx->node_stack = g_slist_prepend (ctx->node_stack, node);
339 static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
340 gboolean in_gobject);
348 static BasicTypeInfo basic_types[] = {
349 { "none", GI_TYPE_TAG_VOID, 0 },
350 { "any", GI_TYPE_TAG_VOID, 1 },
352 { "bool", GI_TYPE_TAG_BOOLEAN, 0 },
353 { "char", GI_TYPE_TAG_INT8, 0 },
354 { "int8", GI_TYPE_TAG_INT8, 0 },
355 { "uint8", GI_TYPE_TAG_UINT8, 0 },
356 { "int16", GI_TYPE_TAG_INT16, 0 },
357 { "uint16", GI_TYPE_TAG_UINT16, 0 },
358 { "int32", GI_TYPE_TAG_INT32, 0 },
359 { "uint32", GI_TYPE_TAG_UINT32, 0 },
360 { "int64", GI_TYPE_TAG_INT64, 0 },
361 { "uint64", GI_TYPE_TAG_UINT64, 0 },
362 { "int", GI_TYPE_TAG_INT, 0 },
363 { "uint", GI_TYPE_TAG_UINT, 0 },
364 { "long", GI_TYPE_TAG_LONG, 0 },
365 { "ulong", GI_TYPE_TAG_ULONG, 0 },
366 { "ssize_t", GI_TYPE_TAG_SSIZE, 0 },
367 { "ssize", GI_TYPE_TAG_SSIZE, 0 },
368 { "size_t", GI_TYPE_TAG_SIZE, 0 },
369 { "size", GI_TYPE_TAG_SIZE, 0 },
370 { "float", GI_TYPE_TAG_FLOAT, 0 },
371 { "double", GI_TYPE_TAG_DOUBLE, 0 },
372 { "time_t", GI_TYPE_TAG_TIME_T, 0 },
373 { "GType", GI_TYPE_TAG_GTYPE, 0 },
374 { "utf8", GI_TYPE_TAG_UTF8, 1 },
375 { "filename", GI_TYPE_TAG_FILENAME,1 },
378 static const BasicTypeInfo *
379 parse_basic (const char *str)
382 gint n_basic = G_N_ELEMENTS (basic_types);
384 for (i = 0; i < n_basic; i++)
386 if (g_str_has_prefix (str, basic_types[i].str))
387 return &(basic_types[i]);
393 parse_type_internal (const gchar *str, char **next, gboolean in_glib,
396 const BasicTypeInfo *basic;
398 char *temporary_type = NULL;
400 type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
402 type->unparsed = g_strdup (str);
404 /* See comment below on GLib.List handling */
405 if (in_gobject && strcmp (str, "Type") == 0)
407 temporary_type = g_strdup ("GLib.Type");
408 str = temporary_type;
411 basic = parse_basic (str);
414 type->is_basic = TRUE;
415 type->tag = basic->tag;
416 type->is_pointer = basic->pointer;
418 str += strlen(basic->str);
422 /* If we're inside GLib, handle "List" etc. by prefixing with
423 * "GLib." so the parsing code below doesn't have to get more
426 if (g_str_has_prefix (str, "List<") ||
427 strcmp (str, "List") == 0)
429 temporary_type = g_strdup_printf ("GLib.List%s", str + 4);
430 str = temporary_type;
432 else if (g_str_has_prefix (str, "SList<") ||
433 strcmp (str, "SList") == 0)
435 temporary_type = g_strdup_printf ("GLib.SList%s", str + 5);
436 str = temporary_type;
438 else if (g_str_has_prefix (str, "HashTable<") ||
439 strcmp (str, "HashTable") == 0)
441 temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9);
442 str = temporary_type;
444 else if (g_str_has_prefix (str, "Error<") ||
445 strcmp (str, "Error") == 0)
447 temporary_type = g_strdup_printf ("GLib.Error%s", str + 5);
448 str = temporary_type;
453 /* found a basic type */;
454 else if (g_str_has_prefix (str, "GLib.List") ||
455 g_str_has_prefix (str, "GLib.SList"))
457 str += strlen ("GLib.");
458 if (g_str_has_prefix (str, "List"))
460 type->tag = GI_TYPE_TAG_GLIST;
461 type->is_glist = TRUE;
462 type->is_pointer = TRUE;
463 str += strlen ("List");
467 type->tag = GI_TYPE_TAG_GSLIST;
468 type->is_gslist = TRUE;
469 type->is_pointer = TRUE;
470 str += strlen ("SList");
473 else if (g_str_has_prefix (str, "GLib.HashTable"))
475 str += strlen ("GLib.");
477 type->tag = GI_TYPE_TAG_GHASH;
478 type->is_ghashtable = TRUE;
479 type->is_pointer = TRUE;
480 str += strlen ("HashTable");
482 else if (g_str_has_prefix (str, "GLib.Error"))
484 str += strlen ("GLib.");
486 type->tag = GI_TYPE_TAG_ERROR;
487 type->is_error = TRUE;
488 type->is_pointer = TRUE;
489 str += strlen ("Error");
496 end = strchr (str, '>');
497 tmp = g_strndup (str, end - str);
498 type->errors = g_strsplit (tmp, ",", 0);
506 type->tag = GI_TYPE_TAG_INTERFACE;
507 type->is_interface = TRUE;
508 const char *start = str;
510 /* must be an interface type */
511 while (g_ascii_isalnum (*str) ||
518 type->interface = g_strndup (start, str - start);
523 g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR);
524 g_free (temporary_type);
528 g_ir_node_free ((GIrNode *)type);
529 g_free (temporary_type);
534 resolve_aliases (ParseContext *ctx, const gchar *type)
538 GSList *seen_values = NULL;
542 if (strchr (type, '.') == NULL)
544 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
553 seen_values = g_slist_prepend (seen_values, (char*)lookup);
554 while (g_hash_table_lookup_extended (ctx->current_module->aliases, lookup, &orig, &value))
556 g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
558 if (g_slist_find_custom (seen_values, lookup,
559 (GCompareFunc)strcmp) != NULL)
561 seen_values = g_slist_prepend (seen_values, (gchar*)lookup);
563 g_slist_free (seen_values);
565 if (lookup == prefixed)
574 is_disguised_structure (ParseContext *ctx, const gchar *type)
580 if (strchr (type, '.') == NULL)
582 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
591 result = g_hash_table_lookup (ctx->current_module->disguised_structures,
600 parse_type (ParseContext *ctx, const gchar *type)
603 const BasicTypeInfo *basic;
604 gboolean in_glib, in_gobject;
606 in_glib = strcmp (ctx->namespace, "GLib") == 0;
607 in_gobject = strcmp (ctx->namespace, "GObject") == 0;
609 /* Do not search aliases for basic types */
610 basic = parse_basic (type);
612 type = resolve_aliases (ctx, type);
614 node = parse_type_internal (type, NULL, in_glib, in_gobject);
616 g_debug ("Parsed type: %s => %d", type, node->tag);
618 g_critical ("Failed to parse type: '%s'", type);
624 start_glib_boxed (GMarkupParseContext *context,
625 const gchar *element_name,
626 const gchar **attribute_names,
627 const gchar **attribute_values,
632 const gchar *typename;
633 const gchar *typeinit;
634 const gchar *deprecated;
637 if (!(strcmp (element_name, "glib:boxed") == 0 &&
638 ctx->state == STATE_NAMESPACE))
641 name = find_attribute ("glib:name", attribute_names, attribute_values);
642 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
643 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
644 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
648 MISSING_ATTRIBUTE (context, error, element_name, "glib:name");
651 else if (typename == NULL)
653 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
656 else if (typeinit == NULL)
658 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
662 boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED);
664 ((GIrNode *)boxed)->name = g_strdup (name);
665 boxed->gtype_name = g_strdup (typename);
666 boxed->gtype_init = g_strdup (typeinit);
668 boxed->deprecated = TRUE;
670 boxed->deprecated = FALSE;
672 push_node (ctx, (GIrNode *)boxed);
673 ctx->current_module->entries =
674 g_list_append (ctx->current_module->entries, boxed);
676 state_switch (ctx, STATE_BOXED);
682 start_function (GMarkupParseContext *context,
683 const gchar *element_name,
684 const gchar **attribute_names,
685 const gchar **attribute_values,
691 const gchar *deprecated;
693 GIrNodeFunction *function;
694 gboolean found = FALSE;
698 case STATE_NAMESPACE:
699 found = (strcmp (element_name, "function") == 0 ||
700 strcmp (element_name, "callback") == 0);
703 found = strcmp (element_name, "function") == 0;
708 found = (found || strcmp (element_name, "constructor") == 0);
710 case STATE_INTERFACE:
712 strcmp (element_name, "method") == 0 ||
713 strcmp (element_name, "callback") == 0);
722 name = find_attribute ("name", attribute_names, attribute_values);
723 symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
724 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
725 throws = find_attribute ("throws", attribute_names, attribute_values);
729 MISSING_ATTRIBUTE (context, error, element_name, "name");
732 else if (strcmp (element_name, "callback") != 0 && symbol == NULL)
734 MISSING_ATTRIBUTE (context, error, element_name, "c:identifier");
738 function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION);
740 ((GIrNode *)function)->name = g_strdup (name);
741 function->symbol = g_strdup (symbol);
742 function->parameters = NULL;
744 function->deprecated = TRUE;
746 function->deprecated = FALSE;
748 if (strcmp (element_name, "method") == 0 ||
749 strcmp (element_name, "constructor") == 0)
751 function->is_method = TRUE;
753 if (strcmp (element_name, "constructor") == 0)
754 function->is_constructor = TRUE;
756 function->is_constructor = FALSE;
760 function->is_method = FALSE;
761 function->is_setter = FALSE;
762 function->is_getter = FALSE;
763 function->is_constructor = FALSE;
764 if (strcmp (element_name, "callback") == 0)
765 ((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
768 if (throws && strcmp (throws, "1") == 0)
769 function->throws = TRUE;
771 function->throws = FALSE;
773 if (ctx->node_stack == NULL)
775 ctx->current_module->entries =
776 g_list_append (ctx->current_module->entries, function);
779 switch (CURRENT_NODE (ctx)->type)
781 case G_IR_NODE_INTERFACE:
782 case G_IR_NODE_OBJECT:
784 GIrNodeInterface *iface;
786 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
787 iface->members = g_list_append (iface->members, function);
790 case G_IR_NODE_BOXED:
794 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
795 boxed->members = g_list_append (boxed->members, function);
798 case G_IR_NODE_STRUCT:
800 GIrNodeStruct *struct_;
802 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
803 struct_->members = g_list_append (struct_->members, function); }
805 case G_IR_NODE_UNION:
807 GIrNodeUnion *union_;
809 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
810 union_->members = g_list_append (union_->members, function);
814 g_assert_not_reached ();
817 push_node(ctx, (GIrNode *)function);
818 state_switch (ctx, STATE_FUNCTION);
824 parse_param_transfer (GIrNodeParam *param, const gchar *transfer)
826 if (transfer == NULL)
828 g_warning ("required attribute 'transfer-ownership' missing");
830 else if (strcmp (transfer, "none") == 0)
832 param->transfer = FALSE;
833 param->shallow_transfer = FALSE;
835 else if (strcmp (transfer, "container") == 0)
837 param->transfer = FALSE;
838 param->shallow_transfer = TRUE;
840 else if (strcmp (transfer, "full") == 0)
842 param->transfer = TRUE;
843 param->shallow_transfer = FALSE;
847 g_warning ("Unknown transfer-ownership value: %s", transfer);
852 start_parameter (GMarkupParseContext *context,
853 const gchar *element_name,
854 const gchar **attribute_names,
855 const gchar **attribute_values,
860 const gchar *direction;
863 const gchar *optional;
864 const gchar *allow_none;
865 const gchar *transfer;
867 const gchar *closure;
868 const gchar *destroy;
871 if (!(strcmp (element_name, "parameter") == 0 &&
872 ctx->state == STATE_FUNCTION_PARAMETERS))
875 name = find_attribute ("name", attribute_names, attribute_values);
876 direction = find_attribute ("direction", attribute_names, attribute_values);
877 retval = find_attribute ("retval", attribute_names, attribute_values);
878 dipper = find_attribute ("dipper", attribute_names, attribute_values);
879 optional = find_attribute ("optional", attribute_names, attribute_values);
880 allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
881 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
882 scope = find_attribute ("scope", attribute_names, attribute_values);
883 closure = find_attribute ("closure", attribute_names, attribute_values);
884 destroy = find_attribute ("destroy", attribute_names, attribute_values);
889 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
891 ctx->current_typed = (GIrNode*) param;
892 ctx->current_typed->name = g_strdup (name);
894 state_switch (ctx, STATE_FUNCTION_PARAMETER);
896 if (direction && strcmp (direction, "out") == 0)
901 else if (direction && strcmp (direction, "inout") == 0)
912 if (retval && strcmp (retval, "1") == 0)
913 param->retval = TRUE;
915 param->retval = FALSE;
917 if (dipper && strcmp (dipper, "1") == 0)
918 param->dipper = TRUE;
920 param->dipper = FALSE;
922 if (optional && strcmp (optional, "1") == 0)
923 param->optional = TRUE;
925 param->optional = FALSE;
927 if (allow_none && strcmp (allow_none, "1") == 0)
928 param->allow_none = TRUE;
930 param->allow_none = FALSE;
932 parse_param_transfer (param, transfer);
934 if (scope && strcmp (scope, "call") == 0)
935 param->scope = GI_SCOPE_TYPE_CALL;
936 else if (scope && strcmp (scope, "object") == 0)
937 param->scope = GI_SCOPE_TYPE_OBJECT;
938 else if (scope && strcmp (scope, "async") == 0)
939 param->scope = GI_SCOPE_TYPE_ASYNC;
940 else if (scope && strcmp (scope, "notified") == 0)
941 param->scope = GI_SCOPE_TYPE_NOTIFIED;
943 param->scope = GI_SCOPE_TYPE_INVALID;
945 param->closure = closure ? atoi (closure) : -1;
946 param->destroy = destroy ? atoi (destroy) : -1;
948 ((GIrNode *)param)->name = g_strdup (name);
950 switch (CURRENT_NODE (ctx)->type)
952 case G_IR_NODE_FUNCTION:
953 case G_IR_NODE_CALLBACK:
955 GIrNodeFunction *func;
957 func = (GIrNodeFunction *)CURRENT_NODE (ctx);
958 func->parameters = g_list_append (func->parameters, param);
961 case G_IR_NODE_SIGNAL:
963 GIrNodeSignal *signal;
965 signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
966 signal->parameters = g_list_append (signal->parameters, param);
969 case G_IR_NODE_VFUNC:
973 vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
974 vfunc->parameters = g_list_append (vfunc->parameters, param);
978 g_assert_not_reached ();
985 start_field (GMarkupParseContext *context,
986 const gchar *element_name,
987 const gchar **attribute_names,
988 const gchar **attribute_values,
993 const gchar *readable;
994 const gchar *writable;
1005 case STATE_INTERFACE:
1011 if (strcmp (element_name, "field") != 0)
1014 name = find_attribute ("name", attribute_names, attribute_values);
1015 readable = find_attribute ("readable", attribute_names, attribute_values);
1016 writable = find_attribute ("writable", attribute_names, attribute_values);
1017 bits = find_attribute ("bits", attribute_names, attribute_values);
1018 branch = find_attribute ("branch", attribute_names, attribute_values);
1022 MISSING_ATTRIBUTE (context, error, element_name, "name");
1026 field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD);
1027 ctx->current_typed = (GIrNode*) field;
1028 ((GIrNode *)field)->name = g_strdup (name);
1029 /* Fields are assumed to be read-only.
1030 * (see also girwriter.py and generate.c)
1032 field->readable = readable == NULL || strcmp (readable, "0") == 0;
1033 field->writable = writable != NULL && strcmp (writable, "1") == 0;
1036 field->bits = atoi (bits);
1040 switch (CURRENT_NODE (ctx)->type)
1042 case G_IR_NODE_OBJECT:
1044 GIrNodeInterface *iface;
1046 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1047 iface->members = g_list_append (iface->members, field);
1048 state_switch (ctx, STATE_CLASS_FIELD);
1051 case G_IR_NODE_INTERFACE:
1053 GIrNodeInterface *iface;
1055 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1056 iface->members = g_list_append (iface->members, field);
1057 state_switch (ctx, STATE_INTERFACE_FIELD);
1060 case G_IR_NODE_BOXED:
1062 GIrNodeBoxed *boxed;
1064 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
1065 boxed->members = g_list_append (boxed->members, field);
1066 state_switch (ctx, STATE_BOXED_FIELD);
1069 case G_IR_NODE_STRUCT:
1071 GIrNodeStruct *struct_;
1073 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
1074 struct_->members = g_list_append (struct_->members, field);
1075 state_switch (ctx, STATE_STRUCT_FIELD);
1078 case G_IR_NODE_UNION:
1080 GIrNodeUnion *union_;
1082 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
1083 union_->members = g_list_append (union_->members, field);
1086 GIrNodeConstant *constant;
1088 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1089 ((GIrNode *)constant)->name = g_strdup (name);
1090 constant->value = g_strdup (branch);
1091 constant->type = union_->discriminator_type;
1092 constant->deprecated = FALSE;
1094 union_->discriminators = g_list_append (union_->discriminators, constant);
1096 state_switch (ctx, STATE_UNION_FIELD);
1100 g_assert_not_reached ();
1107 start_alias (GMarkupParseContext *context,
1108 const gchar *element_name,
1109 const gchar **attribute_names,
1110 const gchar **attribute_values,
1115 const gchar *target;
1119 name = find_attribute ("name", attribute_names, attribute_values);
1122 MISSING_ATTRIBUTE (context, error, element_name, "name");
1126 target = find_attribute ("target", attribute_names, attribute_values);
1129 MISSING_ATTRIBUTE (context, error, element_name, "target");
1133 value = g_strdup (target);
1134 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
1135 if (!strchr (target, '.'))
1137 const BasicTypeInfo *basic = parse_basic (target);
1141 /* For non-basic types, re-qualify the interface */
1142 value = g_strdup_printf ("%s.%s", ctx->namespace, target);
1145 g_hash_table_replace (ctx->aliases, key, value);
1151 start_enum (GMarkupParseContext *context,
1152 const gchar *element_name,
1153 const gchar **attribute_names,
1154 const gchar **attribute_values,
1158 if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
1159 (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))
1162 const gchar *typename;
1163 const gchar *typeinit;
1164 const gchar *deprecated;
1166 name = find_attribute ("name", attribute_names, attribute_values);
1167 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1168 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1169 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1172 MISSING_ATTRIBUTE (context, error, element_name, "name");
1177 if (strcmp (element_name, "enumeration") == 0)
1178 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM);
1180 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS);
1181 ((GIrNode *)enum_)->name = g_strdup (name);
1182 enum_->gtype_name = g_strdup (typename);
1183 enum_->gtype_init = g_strdup (typeinit);
1185 enum_->deprecated = TRUE;
1187 enum_->deprecated = FALSE;
1189 push_node (ctx, (GIrNode *) enum_);
1190 ctx->current_module->entries =
1191 g_list_append (ctx->current_module->entries, enum_);
1193 state_switch (ctx, STATE_ENUM);
1202 start_property (GMarkupParseContext *context,
1203 const gchar *element_name,
1204 const gchar **attribute_names,
1205 const gchar **attribute_values,
1209 if (strcmp (element_name, "property") == 0 &&
1210 (ctx->state == STATE_CLASS ||
1211 ctx->state == STATE_INTERFACE))
1214 const gchar *readable;
1215 const gchar *writable;
1216 const gchar *construct;
1217 const gchar *construct_only;
1219 name = find_attribute ("name", attribute_names, attribute_values);
1220 readable = find_attribute ("readable", attribute_names, attribute_values);
1221 writable = find_attribute ("writable", attribute_names, attribute_values);
1222 construct = find_attribute ("construct", attribute_names, attribute_values);
1223 construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
1226 MISSING_ATTRIBUTE (context, error, element_name, "name");
1229 GIrNodeProperty *property;
1230 GIrNodeInterface *iface;
1232 property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
1233 ctx->current_typed = (GIrNode*) property;
1235 ((GIrNode *)property)->name = g_strdup (name);
1237 /* Assume properties are readable */
1238 if (readable == NULL || strcmp (readable, "1") == 0)
1239 property->readable = TRUE;
1241 property->readable = FALSE;
1242 if (writable && strcmp (writable, "1") == 0)
1243 property->writable = TRUE;
1245 property->writable = FALSE;
1246 if (construct && strcmp (construct, "1") == 0)
1247 property->construct = TRUE;
1249 property->construct = FALSE;
1250 if (construct_only && strcmp (construct_only, "1") == 0)
1251 property->construct_only = TRUE;
1253 property->construct_only = FALSE;
1255 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1256 iface->members = g_list_append (iface->members, property);
1258 if (ctx->state == STATE_CLASS)
1259 state_switch (ctx, STATE_CLASS_PROPERTY);
1260 else if (ctx->state == STATE_INTERFACE)
1261 state_switch (ctx, STATE_INTERFACE_PROPERTY);
1263 g_assert_not_reached ();
1272 parse_value (const gchar *str)
1276 /* FIXME just a quick hack */
1277 shift_op = strstr (str, "<<");
1283 base = strtol (str, NULL, 10);
1284 shift = strtol (shift_op + 3, NULL, 10);
1286 return base << shift;
1289 return strtol (str, NULL, 10);
1295 start_member (GMarkupParseContext *context,
1296 const gchar *element_name,
1297 const gchar **attribute_names,
1298 const gchar **attribute_values,
1302 if (strcmp (element_name, "member") == 0 &&
1303 ctx->state == STATE_ENUM)
1307 const gchar *deprecated;
1309 name = find_attribute ("name", attribute_names, attribute_values);
1310 value = find_attribute ("value", attribute_names, attribute_values);
1311 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1314 MISSING_ATTRIBUTE (context, error, element_name, "name");
1318 GIrNodeValue *value_;
1320 value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
1322 ((GIrNode *)value_)->name = g_strdup (name);
1324 value_->value = parse_value (value);
1327 value_->deprecated = TRUE;
1329 value_->deprecated = FALSE;
1331 enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx);
1332 enum_->values = g_list_append (enum_->values, value_);
1341 start_constant (GMarkupParseContext *context,
1342 const gchar *element_name,
1343 const gchar **attribute_names,
1344 const gchar **attribute_values,
1348 if (strcmp (element_name, "constant") == 0 &&
1349 (ctx->state == STATE_NAMESPACE ||
1350 ctx->state == STATE_CLASS ||
1351 ctx->state == STATE_INTERFACE))
1355 const gchar *deprecated;
1357 name = find_attribute ("name", attribute_names, attribute_values);
1358 value = find_attribute ("value", attribute_names, attribute_values);
1359 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1362 MISSING_ATTRIBUTE (context, error, element_name, "name");
1363 else if (value == NULL)
1364 MISSING_ATTRIBUTE (context, error, element_name, "value");
1367 GIrNodeConstant *constant;
1369 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1371 ((GIrNode *)constant)->name = g_strdup (name);
1372 constant->value = g_strdup (value);
1374 ctx->current_typed = (GIrNode*) constant;
1377 constant->deprecated = TRUE;
1379 constant->deprecated = FALSE;
1381 if (ctx->state == STATE_NAMESPACE)
1383 push_node (ctx, (GIrNode *) constant);
1384 ctx->current_module->entries =
1385 g_list_append (ctx->current_module->entries, constant);
1389 GIrNodeInterface *iface;
1391 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1392 iface->members = g_list_append (iface->members, constant);
1397 case STATE_NAMESPACE:
1398 state_switch (ctx, STATE_NAMESPACE_CONSTANT);
1401 state_switch (ctx, STATE_CLASS_CONSTANT);
1403 case STATE_INTERFACE:
1404 state_switch (ctx, STATE_INTERFACE_CONSTANT);
1407 g_assert_not_reached ();
1418 start_errordomain (GMarkupParseContext *context,
1419 const gchar *element_name,
1420 const gchar **attribute_names,
1421 const gchar **attribute_values,
1425 if (strcmp (element_name, "errordomain") == 0 &&
1426 ctx->state == STATE_NAMESPACE)
1429 const gchar *getquark;
1431 const gchar *deprecated;
1433 name = find_attribute ("name", attribute_names, attribute_values);
1434 getquark = find_attribute ("get-quark", attribute_names, attribute_values);
1435 codes = find_attribute ("codes", attribute_names, attribute_values);
1436 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1439 MISSING_ATTRIBUTE (context, error, element_name, "name");
1440 else if (getquark == NULL)
1441 MISSING_ATTRIBUTE (context, error, element_name, "getquark");
1442 else if (codes == NULL)
1443 MISSING_ATTRIBUTE (context, error, element_name, "codes");
1446 GIrNodeErrorDomain *domain;
1448 domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
1450 ((GIrNode *)domain)->name = g_strdup (name);
1451 domain->getquark = g_strdup (getquark);
1452 domain->codes = g_strdup (codes);
1455 domain->deprecated = TRUE;
1457 domain->deprecated = FALSE;
1459 push_node (ctx, (GIrNode *) domain);
1460 ctx->current_module->entries =
1461 g_list_append (ctx->current_module->entries, domain);
1463 state_switch (ctx, STATE_ERRORDOMAIN);
1472 start_interface (GMarkupParseContext *context,
1473 const gchar *element_name,
1474 const gchar **attribute_names,
1475 const gchar **attribute_values,
1479 if (strcmp (element_name, "interface") == 0 &&
1480 ctx->state == STATE_NAMESPACE)
1483 const gchar *typename;
1484 const gchar *typeinit;
1485 const gchar *deprecated;
1486 const gchar *glib_type_struct;
1488 name = find_attribute ("name", attribute_names, attribute_values);
1489 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1490 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1491 glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values);
1492 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1495 MISSING_ATTRIBUTE (context, error, element_name, "name");
1496 else if (typename == NULL)
1497 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1498 else if (typeinit == NULL)
1499 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1502 GIrNodeInterface *iface;
1504 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE);
1505 ((GIrNode *)iface)->name = g_strdup (name);
1506 iface->gtype_name = g_strdup (typename);
1507 iface->gtype_init = g_strdup (typeinit);
1508 iface->glib_type_struct = g_strdup (glib_type_struct);
1510 iface->deprecated = TRUE;
1512 iface->deprecated = FALSE;
1514 push_node (ctx, (GIrNode *) iface);
1515 ctx->current_module->entries =
1516 g_list_append (ctx->current_module->entries, iface);
1518 state_switch (ctx, STATE_INTERFACE);
1528 start_class (GMarkupParseContext *context,
1529 const gchar *element_name,
1530 const gchar **attribute_names,
1531 const gchar **attribute_values,
1535 if (strcmp (element_name, "class") == 0 &&
1536 ctx->state == STATE_NAMESPACE)
1539 const gchar *parent;
1540 const gchar *glib_type_struct;
1541 const gchar *typename;
1542 const gchar *typeinit;
1543 const gchar *deprecated;
1544 const gchar *abstract;
1546 name = find_attribute ("name", attribute_names, attribute_values);
1547 parent = find_attribute ("parent", attribute_names, attribute_values);
1548 glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values);
1549 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1550 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1551 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1552 abstract = find_attribute ("abstract", attribute_names, attribute_values);
1555 MISSING_ATTRIBUTE (context, error, element_name, "name");
1556 else if (typename == NULL)
1557 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1558 else if (typeinit == NULL && strcmp (typename, "GObject"))
1559 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1562 GIrNodeInterface *iface;
1564 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT);
1565 ((GIrNode *)iface)->name = g_strdup (name);
1566 iface->gtype_name = g_strdup (typename);
1567 iface->gtype_init = g_strdup (typeinit);
1568 iface->parent = g_strdup (parent);
1569 iface->glib_type_struct = g_strdup (glib_type_struct);
1571 iface->deprecated = TRUE;
1573 iface->deprecated = FALSE;
1575 iface->abstract = abstract && strcmp (abstract, "1") == 0;
1577 push_node (ctx, (GIrNode *) iface);
1578 ctx->current_module->entries =
1579 g_list_append (ctx->current_module->entries, iface);
1581 state_switch (ctx, STATE_CLASS);
1590 start_type (GMarkupParseContext *context,
1591 const gchar *element_name,
1592 const gchar **attribute_names,
1593 const gchar **attribute_values,
1600 gboolean is_varargs;
1601 GIrNodeType *typenode;
1603 is_array = strcmp (element_name, "array") == 0;
1604 is_varargs = strcmp (element_name, "varargs") == 0;
1606 if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
1609 if (ctx->state == STATE_TYPE)
1612 ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters);
1613 ctx->type_parameters = NULL;
1615 else if (ctx->state == STATE_FUNCTION_PARAMETER ||
1616 ctx->state == STATE_FUNCTION_RETURN ||
1617 ctx->state == STATE_STRUCT_FIELD ||
1618 ctx->state == STATE_UNION_FIELD ||
1619 ctx->state == STATE_CLASS_PROPERTY ||
1620 ctx->state == STATE_CLASS_FIELD ||
1621 ctx->state == STATE_INTERFACE_FIELD ||
1622 ctx->state == STATE_INTERFACE_PROPERTY ||
1623 ctx->state == STATE_BOXED_FIELD ||
1624 ctx->state == STATE_NAMESPACE_CONSTANT ||
1625 ctx->state == STATE_CLASS_CONSTANT ||
1626 ctx->state == STATE_INTERFACE_CONSTANT
1629 state_switch (ctx, STATE_TYPE);
1630 ctx->type_depth = 1;
1633 switch (CURRENT_NODE (ctx)->type)
1635 case G_IR_NODE_FUNCTION:
1636 case G_IR_NODE_CALLBACK:
1638 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1639 func->is_varargs = TRUE;
1642 case G_IR_NODE_VFUNC:
1644 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1645 vfunc->is_varargs = TRUE;
1648 /* list others individually rather than with default: so that compiler
1649 * warns if new node types are added without adding them to the switch
1651 case G_IR_NODE_INVALID:
1652 case G_IR_NODE_ENUM:
1653 case G_IR_NODE_FLAGS:
1654 case G_IR_NODE_CONSTANT:
1655 case G_IR_NODE_ERROR_DOMAIN:
1656 case G_IR_NODE_PARAM:
1657 case G_IR_NODE_TYPE:
1658 case G_IR_NODE_PROPERTY:
1659 case G_IR_NODE_SIGNAL:
1660 case G_IR_NODE_VALUE:
1661 case G_IR_NODE_FIELD:
1662 case G_IR_NODE_XREF:
1663 case G_IR_NODE_STRUCT:
1664 case G_IR_NODE_BOXED:
1665 case G_IR_NODE_OBJECT:
1666 case G_IR_NODE_INTERFACE:
1667 case G_IR_NODE_UNION:
1668 g_assert_not_reached ();
1672 ctx->type_stack = NULL;
1673 ctx->type_parameters = NULL;
1676 if (!ctx->current_typed)
1680 G_MARKUP_ERROR_INVALID_CONTENT,
1681 "The element <type> is invalid here");
1694 typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
1696 typenode->tag = GI_TYPE_TAG_ARRAY;
1697 typenode->is_pointer = TRUE;
1698 typenode->is_array = TRUE;
1700 zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
1701 len = find_attribute ("length", attribute_names, attribute_values);
1702 size = find_attribute ("fixed-size", attribute_names, attribute_values);
1704 typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0);
1705 typenode->has_length = len != NULL;
1706 typenode->length = typenode->has_length ? atoi (len) : -1;
1708 typenode->has_size = size != NULL;
1709 typenode->size = typenode->has_size ? atoi (size) : -1;
1714 name = find_attribute ("name", attribute_names, attribute_values);
1717 MISSING_ATTRIBUTE (context, error, element_name, "name");
1720 ctype = find_attribute ("c:type", attribute_names, attribute_values);
1723 const char *cp = ctype + strlen(ctype) - 1;
1724 while (cp > ctype && *cp-- == '*')
1728 if (ctx->current_typed->type == G_IR_NODE_PARAM &&
1729 ((GIrNodeParam *)ctx->current_typed)->out &&
1733 typenode = parse_type (ctx, name);
1735 /* A 'disguised' structure is one where the c:type is a typedef that
1736 * doesn't look like a pointer, but is internally.
1738 if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
1739 is_disguised_structure (ctx, typenode->interface))
1742 if (pointer_depth > 0)
1743 typenode->is_pointer = TRUE;
1746 ctx->type_parameters = g_list_append (ctx->type_parameters, typenode);
1752 end_type_top (ParseContext *ctx)
1754 GIrNodeType *typenode;
1756 if (!ctx->type_parameters)
1759 typenode = (GIrNodeType*)ctx->type_parameters->data;
1761 /* Default to pointer for unspecified containers */
1762 if (typenode->tag == GI_TYPE_TAG_ARRAY ||
1763 typenode->tag == GI_TYPE_TAG_GLIST ||
1764 typenode->tag == GI_TYPE_TAG_GSLIST)
1766 if (typenode->parameter_type1 == NULL)
1767 typenode->parameter_type1 = parse_type (ctx, "any");
1769 else if (typenode->tag == GI_TYPE_TAG_GHASH)
1771 if (typenode->parameter_type1 == NULL)
1773 typenode->parameter_type1 = parse_type (ctx, "any");
1774 typenode->parameter_type2 = parse_type (ctx, "any");
1778 switch (ctx->current_typed->type)
1780 case G_IR_NODE_PARAM:
1782 GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed;
1783 param->type = typenode;
1786 case G_IR_NODE_FIELD:
1788 GIrNodeField *field = (GIrNodeField *)ctx->current_typed;
1789 field->type = typenode;
1792 case G_IR_NODE_PROPERTY:
1794 GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed;
1795 property->type = typenode;
1798 case G_IR_NODE_CONSTANT:
1800 GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed;
1801 constant->type = typenode;
1805 g_printerr("current node is %d\n", CURRENT_NODE (ctx)->type);
1806 g_assert_not_reached ();
1808 g_list_free (ctx->type_parameters);
1811 ctx->type_depth = 0;
1812 ctx->type_parameters = NULL;
1813 ctx->current_typed = NULL;
1817 end_type_recurse (ParseContext *ctx)
1819 GIrNodeType *parent;
1820 GIrNodeType *param = NULL;
1822 parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data;
1823 if (ctx->type_parameters)
1824 param = (GIrNodeType *) ctx->type_parameters->data;
1826 if (parent->tag == GI_TYPE_TAG_ARRAY ||
1827 parent->tag == GI_TYPE_TAG_GLIST ||
1828 parent->tag == GI_TYPE_TAG_GSLIST)
1830 g_assert (param != NULL);
1832 if (parent->parameter_type1 == NULL)
1833 parent->parameter_type1 = param;
1835 g_assert_not_reached ();
1837 else if (parent->tag == GI_TYPE_TAG_GHASH)
1839 g_assert (param != NULL);
1841 if (parent->parameter_type1 == NULL)
1842 parent->parameter_type1 = param;
1843 else if (parent->parameter_type2 == NULL)
1844 parent->parameter_type2 = param;
1846 g_assert_not_reached ();
1848 g_list_free (ctx->type_parameters);
1849 ctx->type_parameters = (GList *)ctx->type_stack->data;
1850 ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
1854 end_type (ParseContext *ctx)
1856 if (ctx->type_depth == 1)
1859 state_switch (ctx, ctx->prev_state);
1863 end_type_recurse (ctx);
1869 start_attribute (GMarkupParseContext *context,
1870 const gchar *element_name,
1871 const gchar **attribute_names,
1872 const gchar **attribute_values,
1880 if (strcmp (element_name, "attribute") != 0 || ctx->node_stack == NULL)
1883 name = find_attribute ("name", attribute_names, attribute_values);
1884 value = find_attribute ("value", attribute_names, attribute_values);
1888 MISSING_ATTRIBUTE (context, error, element_name, "name");
1893 MISSING_ATTRIBUTE (context, error, element_name, "value");
1897 state_switch (ctx, STATE_ATTRIBUTE);
1899 curnode = CURRENT_NODE (ctx);
1901 g_hash_table_insert (curnode->attributes, g_strdup (name), g_strdup (value));
1907 start_return_value (GMarkupParseContext *context,
1908 const gchar *element_name,
1909 const gchar **attribute_names,
1910 const gchar **attribute_values,
1914 if (strcmp (element_name, "return-value") == 0 &&
1915 ctx->state == STATE_FUNCTION)
1917 GIrNodeParam *param;
1918 const gchar *transfer;
1920 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
1923 param->retval = TRUE;
1925 ctx->current_typed = (GIrNode*) param;
1927 state_switch (ctx, STATE_FUNCTION_RETURN);
1929 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1930 parse_param_transfer (param, transfer);
1932 switch (CURRENT_NODE (ctx)->type)
1934 case G_IR_NODE_FUNCTION:
1935 case G_IR_NODE_CALLBACK:
1937 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1938 func->result = param;
1941 case G_IR_NODE_SIGNAL:
1943 GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
1944 signal->result = param;
1947 case G_IR_NODE_VFUNC:
1949 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1950 vfunc->result = param;
1954 g_assert_not_reached ();
1964 start_implements (GMarkupParseContext *context,
1965 const gchar *element_name,
1966 const gchar **attribute_names,
1967 const gchar **attribute_values,
1971 GIrNodeInterface *iface;
1974 if (strcmp (element_name, "implements") != 0 ||
1975 !(ctx->state == STATE_CLASS))
1978 state_switch (ctx, STATE_IMPLEMENTS);
1980 name = find_attribute ("name", attribute_names, attribute_values);
1983 MISSING_ATTRIBUTE (context, error, element_name, "name");
1987 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1988 iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
1994 start_glib_signal (GMarkupParseContext *context,
1995 const gchar *element_name,
1996 const gchar **attribute_names,
1997 const gchar **attribute_values,
2001 if (strcmp (element_name, "glib:signal") == 0 &&
2002 (ctx->state == STATE_CLASS ||
2003 ctx->state == STATE_INTERFACE))
2007 const gchar *no_recurse;
2008 const gchar *detailed;
2009 const gchar *action;
2010 const gchar *no_hooks;
2011 const gchar *has_class_closure;
2013 name = find_attribute ("name", attribute_names, attribute_values);
2014 when = find_attribute ("when", attribute_names, attribute_values);
2015 no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values);
2016 detailed = find_attribute ("detailed", attribute_names, attribute_values);
2017 action = find_attribute ("action", attribute_names, attribute_values);
2018 no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values);
2019 has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values);
2022 MISSING_ATTRIBUTE (context, error, element_name, "name");
2025 GIrNodeInterface *iface;
2026 GIrNodeSignal *signal;
2028 signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
2030 ((GIrNode *)signal)->name = g_strdup (name);
2032 signal->run_first = FALSE;
2033 signal->run_last = FALSE;
2034 signal->run_cleanup = FALSE;
2035 if (when == NULL || strcmp (when, "LAST") == 0)
2036 signal->run_last = TRUE;
2037 else if (strcmp (when, "FIRST") == 0)
2038 signal->run_first = TRUE;
2040 signal->run_cleanup = TRUE;
2042 if (no_recurse && strcmp (no_recurse, "1") == 0)
2043 signal->no_recurse = TRUE;
2045 signal->no_recurse = FALSE;
2046 if (detailed && strcmp (detailed, "1") == 0)
2047 signal->detailed = TRUE;
2049 signal->detailed = FALSE;
2050 if (action && strcmp (action, "1") == 0)
2051 signal->action = TRUE;
2053 signal->action = FALSE;
2054 if (no_hooks && strcmp (no_hooks, "1") == 0)
2055 signal->no_hooks = TRUE;
2057 signal->no_hooks = FALSE;
2058 if (has_class_closure && strcmp (has_class_closure, "1") == 0)
2059 signal->has_class_closure = TRUE;
2061 signal->has_class_closure = FALSE;
2063 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2064 iface->members = g_list_append (iface->members, signal);
2066 push_node (ctx, (GIrNode *)signal);
2067 state_switch (ctx, STATE_FUNCTION);
2076 start_vfunc (GMarkupParseContext *context,
2077 const gchar *element_name,
2078 const gchar **attribute_names,
2079 const gchar **attribute_values,
2083 if (strcmp (element_name, "virtual-method") == 0 &&
2084 (ctx->state == STATE_CLASS ||
2085 ctx->state == STATE_INTERFACE))
2088 const gchar *must_chain_up;
2089 const gchar *override;
2090 const gchar *is_class_closure;
2091 const gchar *offset;
2092 const gchar *invoker;
2094 name = find_attribute ("name", attribute_names, attribute_values);
2095 must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values);
2096 override = find_attribute ("override", attribute_names, attribute_values);
2097 is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values);
2098 offset = find_attribute ("offset", attribute_names, attribute_values);
2099 invoker = find_attribute ("invoker", attribute_names, attribute_values);
2102 MISSING_ATTRIBUTE (context, error, element_name, "name");
2105 GIrNodeInterface *iface;
2106 GIrNodeVFunc *vfunc;
2108 vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
2110 ((GIrNode *)vfunc)->name = g_strdup (name);
2112 if (must_chain_up && strcmp (must_chain_up, "1") == 0)
2113 vfunc->must_chain_up = TRUE;
2115 vfunc->must_chain_up = FALSE;
2117 if (override && strcmp (override, "always") == 0)
2119 vfunc->must_be_implemented = TRUE;
2120 vfunc->must_not_be_implemented = FALSE;
2122 else if (override && strcmp (override, "never") == 0)
2124 vfunc->must_be_implemented = FALSE;
2125 vfunc->must_not_be_implemented = TRUE;
2129 vfunc->must_be_implemented = FALSE;
2130 vfunc->must_not_be_implemented = FALSE;
2133 if (is_class_closure && strcmp (is_class_closure, "1") == 0)
2134 vfunc->is_class_closure = TRUE;
2136 vfunc->is_class_closure = FALSE;
2139 vfunc->offset = atoi (offset);
2143 vfunc->invoker = g_strdup (invoker);
2145 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2146 iface->members = g_list_append (iface->members, vfunc);
2148 push_node (ctx, (GIrNode *)vfunc);
2149 state_switch (ctx, STATE_FUNCTION);
2159 start_struct (GMarkupParseContext *context,
2160 const gchar *element_name,
2161 const gchar **attribute_names,
2162 const gchar **attribute_values,
2166 if (strcmp (element_name, "record") == 0 &&
2167 (ctx->state == STATE_NAMESPACE ||
2168 ctx->state == STATE_UNION ||
2169 ctx->state == STATE_STRUCT ||
2170 ctx->state == STATE_CLASS))
2173 const gchar *deprecated;
2174 const gchar *disguised;
2175 const gchar *gtype_name;
2176 const gchar *gtype_init;
2177 const gchar *gtype_struct;
2178 GIrNodeStruct *struct_;
2180 name = find_attribute ("name", attribute_names, attribute_values);
2181 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2182 disguised = find_attribute ("disguised", attribute_names, attribute_values);
2183 gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
2184 gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
2185 gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values);
2187 if (name == NULL && ctx->node_stack == NULL)
2189 MISSING_ATTRIBUTE (context, error, element_name, "name");
2192 if ((gtype_name == NULL && gtype_init != NULL))
2194 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
2197 if ((gtype_name != NULL && gtype_init == NULL))
2199 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
2203 struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
2205 ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
2207 struct_->deprecated = TRUE;
2209 struct_->deprecated = FALSE;
2211 if (disguised && strcmp (disguised, "1") == 0)
2212 struct_->disguised = TRUE;
2214 struct_->is_gtype_struct = gtype_struct != NULL;
2216 struct_->gtype_name = g_strdup (gtype_name);
2217 struct_->gtype_init = g_strdup (gtype_init);
2219 if (ctx->node_stack == NULL)
2220 ctx->current_module->entries =
2221 g_list_append (ctx->current_module->entries, struct_);
2222 push_node (ctx, (GIrNode *)struct_);
2224 state_switch (ctx, STATE_STRUCT);
2232 start_union (GMarkupParseContext *context,
2233 const gchar *element_name,
2234 const gchar **attribute_names,
2235 const gchar **attribute_values,
2239 if (strcmp (element_name, "union") == 0 &&
2240 (ctx->state == STATE_NAMESPACE ||
2241 ctx->state == STATE_UNION ||
2242 ctx->state == STATE_STRUCT ||
2243 ctx->state == STATE_CLASS))
2246 const gchar *deprecated;
2247 const gchar *typename;
2248 const gchar *typeinit;
2250 name = find_attribute ("name", attribute_names, attribute_values);
2251 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2252 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
2253 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
2255 if (name == NULL && ctx->node_stack == NULL)
2256 MISSING_ATTRIBUTE (context, error, element_name, "name");
2259 GIrNodeUnion *union_;
2261 union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
2263 ((GIrNode *)union_)->name = g_strdup (name ? name : "");
2264 union_->gtype_name = g_strdup (typename);
2265 union_->gtype_init = g_strdup (typeinit);
2267 union_->deprecated = TRUE;
2269 union_->deprecated = FALSE;
2271 if (ctx->node_stack == NULL)
2272 ctx->current_module->entries =
2273 g_list_append (ctx->current_module->entries, union_);
2274 push_node (ctx, (GIrNode *)union_);
2276 state_switch (ctx, STATE_UNION);
2284 start_discriminator (GMarkupParseContext *context,
2285 const gchar *element_name,
2286 const gchar **attribute_names,
2287 const gchar **attribute_values,
2291 if (strcmp (element_name, "discriminator") == 0 &&
2292 ctx->state == STATE_UNION)
2295 const gchar *offset;
2297 type = find_attribute ("type", attribute_names, attribute_values);
2298 offset = find_attribute ("offset", attribute_names, attribute_values);
2300 MISSING_ATTRIBUTE (context, error, element_name, "type");
2301 else if (offset == NULL)
2302 MISSING_ATTRIBUTE (context, error, element_name, "offset");
2304 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type
2305 = parse_type (ctx, type);
2306 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset
2317 parse_include (GMarkupParseContext *context,
2320 const char *version,
2326 gboolean success = FALSE;
2330 for (l = ctx->parser->parsed_modules; l; l = l->next)
2332 GIrModule *m = l->data;
2334 if (strcmp (m->name, name) == 0)
2336 if (strcmp (m->version, version) == 0)
2338 ctx->include_modules = g_list_prepend (ctx->include_modules, m);
2346 G_MARKUP_ERROR_INVALID_CONTENT,
2347 "Module '%s' imported with conflicting versions '%s' and '%s'",
2348 name, m->version, version);
2354 girpath = locate_gir (ctx->parser, name, version);
2356 if (girpath == NULL)
2360 G_MARKUP_ERROR_INVALID_CONTENT,
2361 "Could not find GIR file '%s.gir'; check XDG_DATA_DIRS or use --includedir",
2366 g_debug ("Parsing include %s", girpath);
2368 if (!g_file_get_contents (girpath, &buffer, &length, error))
2375 modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error);
2376 success = error != NULL;
2378 ctx->include_modules = g_list_concat (ctx->include_modules,
2386 extern GLogLevelFlags logged_levels;
2389 start_element_handler (GMarkupParseContext *context,
2390 const gchar *element_name,
2391 const gchar **attribute_names,
2392 const gchar **attribute_values,
2396 ParseContext *ctx = user_data;
2397 gint line_number, char_number;
2399 if (logged_levels & G_LOG_LEVEL_DEBUG)
2401 GString *tags = g_string_new ("");
2403 for (i = 0; attribute_names[i]; i++)
2404 g_string_append_printf (tags, "%s=\"%s\" ",
2406 attribute_values[i]);
2410 g_string_insert_c (tags, 0, ' ');
2411 g_string_truncate (tags, tags->len - 1);
2413 g_debug ("<%s%s>", element_name, tags->str);
2414 g_string_free (tags, TRUE);
2417 switch (element_name[0])
2420 if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0)
2422 state_switch (ctx, STATE_ALIAS);
2425 if (start_type (context, element_name,
2426 attribute_names, attribute_values,
2429 else if (start_attribute (context, element_name,
2430 attribute_names, attribute_values,
2435 if (start_enum (context, element_name,
2436 attribute_names, attribute_values,
2441 if (start_function (context, element_name,
2442 attribute_names, attribute_values,
2445 else if (start_constant (context, element_name,
2446 attribute_names, attribute_values,
2449 else if (start_class (context, element_name,
2450 attribute_names, attribute_values,
2456 if (start_discriminator (context, element_name,
2457 attribute_names, attribute_values,
2463 if (start_enum (context, element_name,
2464 attribute_names, attribute_values,
2467 else if (start_errordomain (context, element_name,
2468 attribute_names, attribute_values,
2474 if (start_function (context, element_name,
2475 attribute_names, attribute_values,
2478 else if (start_field (context, element_name,
2479 attribute_names, attribute_values,
2485 if (start_glib_boxed (context, element_name,
2486 attribute_names, attribute_values,
2489 else if (start_glib_signal (context, element_name,
2490 attribute_names, attribute_values,
2496 if (strcmp (element_name, "include") == 0 &&
2497 ctx->state == STATE_REPOSITORY)
2500 const gchar *version;
2502 name = find_attribute ("name", attribute_names, attribute_values);
2503 version = find_attribute ("version", attribute_names, attribute_values);
2507 MISSING_ATTRIBUTE (context, error, element_name, "name");
2510 if (version == NULL)
2512 MISSING_ATTRIBUTE (context, error, element_name, "version");
2516 if (!parse_include (context, ctx, name, version, error))
2519 ctx->dependencies = g_list_prepend (ctx->dependencies,
2520 g_strdup_printf ("%s-%s", name, version));
2523 state_switch (ctx, STATE_INCLUDE);
2526 if (start_interface (context, element_name,
2527 attribute_names, attribute_values,
2530 else if (start_implements (context, element_name,
2531 attribute_names, attribute_values,
2537 if (start_function (context, element_name,
2538 attribute_names, attribute_values,
2541 else if (start_member (context, element_name,
2542 attribute_names, attribute_values,
2548 if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2550 const gchar *name, *version, *shared_library;
2552 if (ctx->current_module != NULL)
2556 G_MARKUP_ERROR_INVALID_CONTENT,
2557 "Only one <namespace/> element is currently allowed per <repository/>");
2561 name = find_attribute ("name", attribute_names, attribute_values);
2562 version = find_attribute ("version", attribute_names, attribute_values);
2563 shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2566 MISSING_ATTRIBUTE (context, error, element_name, "name");
2567 else if (version == NULL)
2568 MISSING_ATTRIBUTE (context, error, element_name, "version");
2573 if (strcmp (name, ctx->namespace) != 0)
2576 G_MARKUP_ERROR_INVALID_CONTENT,
2577 "<namespace/> name element '%s' doesn't match file name '%s'",
2578 name, ctx->namespace);
2580 ctx->current_module = g_ir_module_new (name, version, shared_library);
2582 ctx->current_module->aliases = ctx->aliases;
2583 ctx->aliases = NULL;
2584 ctx->current_module->disguised_structures = ctx->disguised_structures;
2585 ctx->disguised_structures = NULL;
2587 for (l = ctx->include_modules; l; l = l->next)
2588 g_ir_module_add_include_module (ctx->current_module, l->data);
2590 g_list_free (ctx->include_modules);
2591 ctx->include_modules = NULL;
2593 ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2594 ctx->current_module->dependencies = ctx->dependencies;
2596 state_switch (ctx, STATE_NAMESPACE);
2603 if (start_property (context, element_name,
2604 attribute_names, attribute_values,
2607 else if (strcmp (element_name, "parameters") == 0 &&
2608 ctx->state == STATE_FUNCTION)
2610 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2614 else if (start_parameter (context, element_name,
2615 attribute_names, attribute_values,
2618 else if (strcmp (element_name, "prerequisite") == 0 &&
2619 ctx->state == STATE_INTERFACE)
2623 name = find_attribute ("name", attribute_names, attribute_values);
2625 state_switch (ctx, STATE_PREREQUISITE);
2628 MISSING_ATTRIBUTE (context, error, element_name, "name");
2631 GIrNodeInterface *iface;
2633 iface = (GIrNodeInterface *)CURRENT_NODE(ctx);
2634 iface->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
2638 else if (strcmp (element_name, "package") == 0 &&
2639 ctx->state == STATE_REPOSITORY)
2641 state_switch (ctx, STATE_PACKAGE);
2647 if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
2649 const gchar *version;
2651 version = find_attribute ("version", attribute_names, attribute_values);
2653 if (version == NULL)
2654 MISSING_ATTRIBUTE (context, error, element_name, "version");
2655 else if (strcmp (version, "1.0") != 0)
2658 G_MARKUP_ERROR_INVALID_CONTENT,
2659 "Unsupported version '%s'",
2662 state_switch (ctx, STATE_REPOSITORY);
2666 else if (start_return_value (context, element_name,
2667 attribute_names, attribute_values,
2670 else if (start_struct (context, element_name,
2671 attribute_names, attribute_values,
2677 if (start_union (context, element_name,
2678 attribute_names, attribute_values,
2684 if (start_type (context, element_name,
2685 attribute_names, attribute_values,
2691 if (start_vfunc (context, element_name,
2692 attribute_names, attribute_values,
2695 if (start_type (context, element_name,
2696 attribute_names, attribute_values,
2702 if (ctx->state != STATE_UNKNOWN)
2704 state_switch (ctx, STATE_UNKNOWN);
2705 ctx->unknown_depth = 1;
2709 ctx->unknown_depth += 1;
2715 g_markup_parse_context_get_position (context, &line_number, &char_number);
2717 fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message);
2718 backtrace_stderr ();
2723 require_one_of_end_elements (GMarkupParseContext *context,
2725 const char *actual_name,
2730 int line_number, char_number;
2731 const char *expected;
2732 gboolean matched = FALSE;
2734 va_start (args, error);
2736 while ((expected = va_arg (args, const char*)) != NULL)
2738 if (strcmp (expected, actual_name) == 0)
2750 g_markup_parse_context_get_position (context, &line_number, &char_number);
2753 G_MARKUP_ERROR_INVALID_CONTENT,
2754 "Unexpected end tag '%s' on line %d char %d; current state=%d",
2756 line_number, char_number, ctx->state);
2762 state_switch_end_struct_or_union (GMarkupParseContext *context,
2764 const gchar *element_name,
2768 if (ctx->node_stack == NULL)
2770 state_switch (ctx, STATE_NAMESPACE);
2774 if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2775 state_switch (ctx, STATE_STRUCT);
2776 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2777 state_switch (ctx, STATE_UNION);
2778 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2779 state_switch (ctx, STATE_CLASS);
2782 int line_number, char_number;
2783 g_markup_parse_context_get_position (context, &line_number, &char_number);
2786 G_MARKUP_ERROR_INVALID_CONTENT,
2787 "Unexpected end tag '%s' on line %d char %d",
2789 line_number, char_number);
2797 require_end_element (GMarkupParseContext *context,
2799 const char *expected_name,
2800 const char *actual_name,
2803 return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
2807 end_element_handler (GMarkupParseContext *context,
2808 const gchar *element_name,
2812 ParseContext *ctx = user_data;
2814 g_debug ("</%s>", element_name);
2820 /* no need to GError here, GMarkup already catches this */
2823 case STATE_REPOSITORY:
2824 state_switch (ctx, STATE_END);
2828 if (require_end_element (context, ctx, "include", element_name, error))
2830 state_switch (ctx, STATE_REPOSITORY);
2835 if (require_end_element (context, ctx, "package", element_name, error))
2837 state_switch (ctx, STATE_REPOSITORY);
2841 case STATE_NAMESPACE:
2842 if (require_end_element (context, ctx, "namespace", element_name, error))
2844 ctx->current_module = NULL;
2845 state_switch (ctx, STATE_REPOSITORY);
2850 if (require_end_element (context, ctx, "alias", element_name, error))
2852 state_switch (ctx, STATE_NAMESPACE);
2856 case STATE_FUNCTION_RETURN:
2857 if (strcmp ("type", element_name) == 0)
2859 if (require_end_element (context, ctx, "return-value", element_name, error))
2861 state_switch (ctx, STATE_FUNCTION);
2865 case STATE_FUNCTION_PARAMETERS:
2866 if (require_end_element (context, ctx, "parameters", element_name, error))
2868 state_switch (ctx, STATE_FUNCTION);
2872 case STATE_FUNCTION_PARAMETER:
2873 if (strcmp ("type", element_name) == 0)
2875 if (require_end_element (context, ctx, "parameter", element_name, error))
2877 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2881 case STATE_FUNCTION:
2884 if (ctx->node_stack == NULL)
2886 state_switch (ctx, STATE_NAMESPACE);
2890 if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
2891 state_switch (ctx, STATE_INTERFACE);
2892 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2893 state_switch (ctx, STATE_CLASS);
2894 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_BOXED)
2895 state_switch (ctx, STATE_BOXED);
2896 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2897 state_switch (ctx, STATE_STRUCT);
2898 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2899 state_switch (ctx, STATE_UNION);
2902 int line_number, char_number;
2903 g_markup_parse_context_get_position (context, &line_number, &char_number);
2906 G_MARKUP_ERROR_INVALID_CONTENT,
2907 "Unexpected end tag '%s' on line %d char %d",
2909 line_number, char_number);
2915 case STATE_CLASS_FIELD:
2916 if (strcmp ("type", element_name) == 0)
2918 if (require_end_element (context, ctx, "field", element_name, error))
2920 state_switch (ctx, STATE_CLASS);
2924 case STATE_CLASS_PROPERTY:
2925 if (strcmp ("type", element_name) == 0)
2927 if (require_end_element (context, ctx, "property", element_name, error))
2929 state_switch (ctx, STATE_CLASS);
2934 if (require_end_element (context, ctx, "class", element_name, error))
2937 state_switch (ctx, STATE_NAMESPACE);
2941 case STATE_ERRORDOMAIN:
2942 if (require_end_element (context, ctx, "errordomain", element_name, error))
2945 state_switch (ctx, STATE_NAMESPACE);
2949 case STATE_INTERFACE_PROPERTY:
2950 if (strcmp ("type", element_name) == 0)
2952 if (require_end_element (context, ctx, "property", element_name, error))
2954 state_switch (ctx, STATE_INTERFACE);
2958 case STATE_INTERFACE_FIELD:
2959 if (strcmp ("type", element_name) == 0)
2961 if (require_end_element (context, ctx, "field", element_name, error))
2963 state_switch (ctx, STATE_INTERFACE);
2967 case STATE_INTERFACE:
2968 if (require_end_element (context, ctx, "interface", element_name, error))
2971 state_switch (ctx, STATE_NAMESPACE);
2976 if (strcmp ("member", element_name) == 0)
2978 else if (require_one_of_end_elements (context, ctx,
2979 element_name, error, "enumeration",
2983 state_switch (ctx, STATE_NAMESPACE);
2988 if (require_end_element (context, ctx, "glib:boxed", element_name, error))
2991 state_switch (ctx, STATE_NAMESPACE);
2995 case STATE_BOXED_FIELD:
2996 if (strcmp ("type", element_name) == 0)
2998 if (require_end_element (context, ctx, "field", element_name, error))
3000 state_switch (ctx, STATE_BOXED);
3004 case STATE_STRUCT_FIELD:
3005 if (strcmp ("type", element_name) == 0)
3007 if (require_end_element (context, ctx, "field", element_name, error))
3009 state_switch (ctx, STATE_STRUCT);
3014 if (require_end_element (context, ctx, "record", element_name, error))
3016 state_switch_end_struct_or_union (context, ctx, element_name, error);
3020 case STATE_UNION_FIELD:
3021 if (strcmp ("type", element_name) == 0)
3023 if (require_end_element (context, ctx, "field", element_name, error))
3025 state_switch (ctx, STATE_UNION);
3030 if (require_end_element (context, ctx, "union", element_name, error))
3032 state_switch_end_struct_or_union (context, ctx, element_name, error);
3035 case STATE_IMPLEMENTS:
3036 if (strcmp ("interface", element_name) == 0)
3038 if (require_end_element (context, ctx, "implements", element_name, error))
3039 state_switch (ctx, STATE_CLASS);
3041 case STATE_PREREQUISITE:
3042 if (require_end_element (context, ctx, "prerequisite", element_name, error))
3043 state_switch (ctx, STATE_INTERFACE);
3045 case STATE_NAMESPACE_CONSTANT:
3046 case STATE_CLASS_CONSTANT:
3047 case STATE_INTERFACE_CONSTANT:
3048 if (strcmp ("type", element_name) == 0)
3050 if (require_end_element (context, ctx, "constant", element_name, error))
3055 case STATE_NAMESPACE_CONSTANT:
3056 state_switch (ctx, STATE_NAMESPACE);
3058 case STATE_CLASS_CONSTANT:
3059 state_switch (ctx, STATE_CLASS);
3061 case STATE_INTERFACE_CONSTANT:
3062 state_switch (ctx, STATE_INTERFACE);
3065 g_assert_not_reached ();
3071 if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
3072 (strcmp ("varargs", element_name) == 0))
3077 case STATE_ATTRIBUTE:
3078 if (strcmp ("attribute", element_name) == 0)
3080 state_switch (ctx, ctx->prev_state);
3085 ctx->unknown_depth -= 1;
3086 if (ctx->unknown_depth == 0)
3087 state_switch (ctx, ctx->prev_state);
3090 g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
3095 text_handler (GMarkupParseContext *context,
3101 /* FIXME warn about non-whitespace text */
3105 cleanup (GMarkupParseContext *context,
3109 ParseContext *ctx = user_data;
3112 for (m = ctx->modules; m; m = m->next)
3113 g_ir_module_free (m->data);
3114 g_list_free (ctx->modules);
3115 ctx->modules = NULL;
3117 ctx->current_module = NULL;
3121 post_filter_toplevel_varargs_functions (GList *list,
3122 GList **varargs_callbacks_out)
3125 GList *varargs_callbacks = *varargs_callbacks_out;
3131 GIrNode *node = iter->data;
3135 if (node->type == G_IR_NODE_FUNCTION)
3137 if (((GIrNodeFunction*)node)->is_varargs)
3139 list = g_list_delete_link (list, link);
3142 if (node->type == G_IR_NODE_CALLBACK)
3144 if (((GIrNodeFunction*)node)->is_varargs)
3146 varargs_callbacks = g_list_append (varargs_callbacks,
3148 list = g_list_delete_link (list, link);
3153 *varargs_callbacks_out = varargs_callbacks;
3159 post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out)
3162 GList *varargs_callbacks;
3164 list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out);
3166 varargs_callbacks = *varargs_callbacks_out;
3172 GIrNode *node = iter->data;
3176 if (node->type == G_IR_NODE_FUNCTION)
3179 gboolean function_done = FALSE;
3181 for (param = ((GIrNodeFunction *)node)->parameters;
3183 param = param->next)
3185 GIrNodeParam *node = (GIrNodeParam *)param->data;
3190 if (node->type->is_interface)
3193 for (callback = varargs_callbacks;
3195 callback = callback->next)
3197 if (!strcmp (node->type->interface,
3198 ((GIrNode *)varargs_callbacks->data)->name))
3200 list = g_list_delete_link (list, link);
3201 function_done = TRUE;
3210 *varargs_callbacks_out = varargs_callbacks;
3216 post_filter (GIrModule *module)
3219 GList *varargs_callbacks = NULL;
3221 module->entries = post_filter_varargs_functions (module->entries,
3222 &varargs_callbacks);
3223 iter = module->entries;
3226 GIrNode *node = iter->data;
3230 if (node->type == G_IR_NODE_OBJECT ||
3231 node->type == G_IR_NODE_INTERFACE)
3233 GIrNodeInterface *iface = (GIrNodeInterface*)node;
3234 iface->members = post_filter_varargs_functions (iface->members,
3235 &varargs_callbacks);
3237 else if (node->type == G_IR_NODE_BOXED)
3239 GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
3240 boxed->members = post_filter_varargs_functions (boxed->members,
3241 &varargs_callbacks);
3243 else if (node->type == G_IR_NODE_STRUCT)
3245 GIrNodeStruct *iface = (GIrNodeStruct*)node;
3246 iface->members = post_filter_varargs_functions (iface->members,
3247 &varargs_callbacks);
3249 else if (node->type == G_IR_NODE_UNION)
3251 GIrNodeUnion *iface = (GIrNodeUnion*)node;
3252 iface->members = post_filter_varargs_functions (iface->members,
3253 &varargs_callbacks);
3256 g_list_free (varargs_callbacks);
3260 * g_ir_parser_parse_string:
3261 * @parser: a #GIrParser
3262 * @namespace: the namespace of the string
3263 * @buffer: the data containing the XML
3264 * @length: length of the data
3265 * @error: return location for a #GError, or %NULL
3267 * Parse a string that holds a complete GIR XML file, and return a list of a
3268 * a #GirModule for each <namespace/> element within the file.
3270 * Returns: a newly allocated list of #GIrModule. The modules themselves
3271 * are owned by the #GIrParser and will be freed along with the parser.
3274 g_ir_parser_parse_string (GIrParser *parser,
3275 const gchar *namespace,
3276 const gchar *buffer,
3280 ParseContext ctx = { 0 };
3281 GMarkupParseContext *context;
3283 ctx.parser = parser;
3284 ctx.state = STATE_START;
3285 ctx.namespace = namespace;
3286 ctx.include_modules = NULL;
3287 ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
3288 ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
3290 ctx.dependencies = NULL;
3291 ctx.current_module = NULL;
3293 context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
3295 if (!g_markup_parse_context_parse (context, buffer, length, error))
3298 if (!g_markup_parse_context_end_parse (context, error))
3301 g_markup_parse_context_free (context);
3303 context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL);
3304 if (!g_markup_parse_context_parse (context, buffer, length, error))
3307 if (!g_markup_parse_context_end_parse (context, error))
3310 parser->parsed_modules = g_list_concat (g_list_copy (ctx.modules),
3311 parser->parsed_modules);
3315 if (ctx.modules == NULL)
3317 /* An error occurred before we created a module, so we haven't
3318 * transferred ownership of these hash tables to the module.
3320 if (ctx.aliases != NULL)
3321 g_hash_table_destroy (ctx.aliases);
3322 if (ctx.disguised_structures != NULL)
3323 g_hash_table_destroy (ctx.disguised_structures);
3324 g_list_free (ctx.include_modules);
3327 g_markup_parse_context_free (context);
3333 * g_ir_parser_parse_file:
3334 * @parser: a #GIrParser
3335 * @filename: filename to parse
3336 * @error: return location for a #GError, or %NULL
3338 * Parse GIR XML file, and return a list of a a #GirModule for each
3339 * <namespace/> element within the file.
3341 * Returns: a newly allocated list of #GIrModule. The modules themselves
3342 * are owned by the #GIrParser and will be freed along with the parser.
3345 g_ir_parser_parse_file (GIrParser *parser,
3346 const gchar *filename,
3357 if (!g_str_has_suffix (filename, ".gir"))
3361 G_MARKUP_ERROR_INVALID_CONTENT,
3362 "Expected filename to end with '.gir'");
3366 g_debug ("[parsing] filename %s", filename);
3368 slash = g_strrstr (filename, "/");
3370 namespace = g_strdup (filename);
3372 namespace = g_strdup (slash+1);
3373 namespace[strlen(namespace)-4] = '\0';
3375 /* Remove version */
3376 dash = strstr (namespace, "-");
3380 if (!g_file_get_contents (filename, &buffer, &length, error))
3383 modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error);
3385 for (iter = modules; iter; iter = iter->next)
3387 post_filter ((GIrModule*)iter->data);