1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 * GObject introspection: A parser for the XML GIR format
4 * Copyright (C) 2005 Matthias Clasen
5 * Copyright (C) 2008 Philip Van Hoof
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
30 #include "girparser.h"
31 #include "girmodule.h"
33 #include "gitypelib-internal.h"
35 /* This is a "major" version in the sense that it's only bumped
36 * for incompatible changes.
38 #define SUPPORTED_GIR_VERSION "1.2"
48 /* GIR_DIR is used only in code called just once,
49 * so no problem leaking this
52 g_build_filename (g_win32_get_package_installation_directory_of_module(NULL), \
61 GList *parsed_modules; /* All previously parsed modules */
71 STATE_C_INCLUDE, /* 5 */
76 STATE_FUNCTION, /* 10 */
77 STATE_FUNCTION_RETURN,
78 STATE_FUNCTION_PARAMETERS,
79 STATE_FUNCTION_PARAMETER,
81 STATE_CLASS_FIELD, /* 15 */
84 STATE_INTERFACE_PROPERTY,
85 STATE_INTERFACE_FIELD,
86 STATE_IMPLEMENTS, /* 20 */
91 STATE_STRUCT_FIELD, /* 25 */
94 STATE_NAMESPACE_CONSTANT,
96 STATE_INTERFACE_CONSTANT, /* 30 */
103 typedef struct _ParseContext ParseContext;
110 ParseState prev_state;
113 GList *include_modules;
116 GHashTable *disguised_structures;
118 const char *file_path;
119 const char *namespace;
120 const char *c_prefix;
121 GIrModule *current_module;
124 GIrNode *current_typed;
126 GList *type_parameters;
128 ParseState in_embedded_state;
130 #define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
132 static void start_element_handler (GMarkupParseContext *context,
133 const gchar *element_name,
134 const gchar **attribute_names,
135 const gchar **attribute_values,
138 static void end_element_handler (GMarkupParseContext *context,
139 const gchar *element_name,
142 static void text_handler (GMarkupParseContext *context,
147 static void cleanup (GMarkupParseContext *context,
150 static void state_switch (ParseContext *ctx, ParseState newstate);
153 static GMarkupParser markup_parser =
155 start_element_handler,
163 start_alias (GMarkupParseContext *context,
164 const gchar *element_name,
165 const gchar **attribute_names,
166 const gchar **attribute_values,
170 start_type (GMarkupParseContext *context,
171 const gchar *element_name,
172 const gchar **attribute_names,
173 const gchar **attribute_values,
177 static const gchar *find_attribute (const gchar *name,
178 const gchar **attribute_names,
179 const gchar **attribute_values);
183 _g_ir_parser_new (void)
185 GIrParser *parser = g_slice_new0 (GIrParser);
191 _g_ir_parser_free (GIrParser *parser)
195 if (parser->includes)
196 g_strfreev (parser->includes);
198 for (l = parser->parsed_modules; l; l = l->next)
199 _g_ir_module_free (l->data);
201 g_slice_free (GIrParser, parser);
205 _g_ir_parser_set_includes (GIrParser *parser,
206 const gchar *const *includes)
208 if (parser->includes)
209 g_strfreev (parser->includes);
211 parser->includes = g_strdupv ((char **)includes);
215 firstpass_start_element_handler (GMarkupParseContext *context,
216 const gchar *element_name,
217 const gchar **attribute_names,
218 const gchar **attribute_values,
222 ParseContext *ctx = user_data;
224 if (strcmp (element_name, "alias") == 0)
226 start_alias (context, element_name, attribute_names, attribute_values,
229 else if (ctx->state == STATE_ALIAS && strcmp (element_name, "type") == 0)
231 start_type (context, element_name, attribute_names, attribute_values,
234 else if (strcmp (element_name, "record") == 0)
237 const gchar *disguised;
239 name = find_attribute ("name", attribute_names, attribute_values);
240 disguised = find_attribute ("disguised", attribute_names, attribute_values);
242 if (disguised && strcmp (disguised, "1") == 0)
246 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
247 g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
253 firstpass_end_element_handler (GMarkupParseContext *context,
254 const gchar *element_name,
258 ParseContext *ctx = user_data;
259 if (strcmp (element_name, "alias") == 0)
261 state_switch (ctx, STATE_NAMESPACE);
262 g_free (ctx->current_alias);
263 ctx->current_alias = NULL;
265 else if (strcmp (element_name, "type") == 0 && ctx->state == STATE_TYPE)
266 state_switch (ctx, ctx->prev_state);
269 static GMarkupParser firstpass_parser =
271 firstpass_start_element_handler,
272 firstpass_end_element_handler,
279 locate_gir (GIrParser *parser,
282 const gchar *const *datadirs;
283 const gchar *const *dir;
286 datadirs = g_get_system_data_dirs ();
288 if (parser->includes != NULL)
290 for (dir = (const gchar *const *)parser->includes; *dir; dir++)
292 path = g_build_filename (*dir, girname, NULL);
293 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
299 for (dir = datadirs; *dir; dir++)
301 path = g_build_filename (*dir, GIR_SUFFIX, girname, NULL);
302 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
308 path = g_build_filename (GIR_DIR, girname, NULL);
309 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
315 #define MISSING_ATTRIBUTE(context,error,element,attribute) \
317 int line_number, char_number; \
318 g_markup_parse_context_get_position (context, &line_number, &char_number); \
319 g_set_error (error, \
321 G_MARKUP_ERROR_INVALID_CONTENT, \
322 "Line %d, character %d: The attribute '%s' on the element '%s' must be specified", \
323 line_number, char_number, attribute, element); \
327 find_attribute (const gchar *name,
328 const gchar **attribute_names,
329 const gchar **attribute_values)
333 for (i = 0; attribute_names[i] != NULL; i++)
334 if (strcmp (attribute_names[i], name) == 0)
335 return attribute_values[i];
341 state_switch (ParseContext *ctx, ParseState newstate)
343 g_assert (ctx->state != newstate);
344 ctx->prev_state = ctx->state;
345 ctx->state = newstate;
347 if (ctx->state == STATE_PASSTHROUGH)
348 ctx->unknown_depth = 1;
352 pop_node (ParseContext *ctx)
356 g_assert (ctx->node_stack != 0);
358 top = ctx->node_stack;
361 g_debug ("popping node %d %s", node->type, node->name);
362 ctx->node_stack = top->next;
363 g_slist_free_1 (top);
368 push_node (ParseContext *ctx, GIrNode *node)
370 g_assert (node != NULL);
371 g_debug ("pushing node %d %s", node->type, node->name);
372 ctx->node_stack = g_slist_prepend (ctx->node_stack, node);
375 static GIrNodeType * parse_type_internal (GIrModule *module,
376 const gchar *str, gchar **next, gboolean in_glib,
377 gboolean in_gobject);
385 static IntegerAliasInfo integer_aliases[] = {
386 { "gchar", SIZEOF_CHAR, 1 },
387 { "guchar", SIZEOF_CHAR, 0 },
388 { "gshort", SIZEOF_SHORT, 1 },
389 { "gushort", SIZEOF_SHORT, 0 },
390 { "gint", SIZEOF_INT, 1 },
391 { "guint", SIZEOF_INT, 0 },
392 { "glong", SIZEOF_LONG, 1 },
393 { "gulong", SIZEOF_LONG, 0 },
394 { "gssize", GLIB_SIZEOF_SIZE_T, 1 },
395 { "gsize", GLIB_SIZEOF_SIZE_T, 0 },
396 { "gintptr", GLIB_SIZEOF_SIZE_T, 1 },
397 { "guintptr", GLIB_SIZEOF_SIZE_T, 0 },
406 #define BASIC_TYPE_FIXED_OFFSET 3
408 static BasicTypeInfo basic_types[] = {
409 { "none", GI_TYPE_TAG_VOID, 0 },
410 { "gpointer", GI_TYPE_TAG_VOID, 1 },
412 { "gboolean", GI_TYPE_TAG_BOOLEAN, 0 },
413 { "gint8", GI_TYPE_TAG_INT8, 0 }, /* Start of BASIC_TYPE_FIXED_OFFSET */
414 { "guint8", GI_TYPE_TAG_UINT8, 0 },
415 { "gint16", GI_TYPE_TAG_INT16, 0 },
416 { "guint16", GI_TYPE_TAG_UINT16, 0 },
417 { "gint32", GI_TYPE_TAG_INT32, 0 },
418 { "guint32", GI_TYPE_TAG_UINT32, 0 },
419 { "gint64", GI_TYPE_TAG_INT64, 0 },
420 { "guint64", GI_TYPE_TAG_UINT64, 0 },
421 { "gfloat", GI_TYPE_TAG_FLOAT, 0 },
422 { "gdouble", GI_TYPE_TAG_DOUBLE, 0 },
423 { "GType", GI_TYPE_TAG_GTYPE, 0 },
424 { "utf8", GI_TYPE_TAG_UTF8, 1 },
425 { "filename", GI_TYPE_TAG_FILENAME,1 },
426 { "gunichar", GI_TYPE_TAG_UNICHAR, 0 },
429 static const BasicTypeInfo *
430 parse_basic (const char *str)
433 guint n_basic = G_N_ELEMENTS (basic_types);
435 for (i = 0; i < n_basic; i++)
437 if (strcmp (str, basic_types[i].str) == 0)
438 return &(basic_types[i]);
440 for (i = 0; i < G_N_ELEMENTS (integer_aliases); i++)
442 if (strcmp (str, integer_aliases[i].str) == 0)
444 switch (integer_aliases[i].size)
447 if (integer_aliases[i].is_signed)
448 return &basic_types[BASIC_TYPE_FIXED_OFFSET];
450 return &basic_types[BASIC_TYPE_FIXED_OFFSET+1];
452 case sizeof(guint16):
453 if (integer_aliases[i].is_signed)
454 return &basic_types[BASIC_TYPE_FIXED_OFFSET+2];
456 return &basic_types[BASIC_TYPE_FIXED_OFFSET+3];
458 case sizeof(guint32):
459 if (integer_aliases[i].is_signed)
460 return &basic_types[BASIC_TYPE_FIXED_OFFSET+4];
462 return &basic_types[BASIC_TYPE_FIXED_OFFSET+5];
464 case sizeof(guint64):
465 if (integer_aliases[i].is_signed)
466 return &basic_types[BASIC_TYPE_FIXED_OFFSET+6];
468 return &basic_types[BASIC_TYPE_FIXED_OFFSET+7];
471 g_assert_not_reached ();
479 parse_type_internal (GIrModule *module,
480 const gchar *str, char **next, gboolean in_glib,
483 const BasicTypeInfo *basic;
485 char *temporary_type = NULL;
487 type = (GIrNodeType *)_g_ir_node_new (G_IR_NODE_TYPE, module);
489 type->unparsed = g_strdup (str);
491 /* See comment below on GLib.List handling */
492 if (in_gobject && strcmp (str, "Type") == 0)
494 temporary_type = g_strdup ("GLib.Type");
495 str = temporary_type;
498 basic = parse_basic (str);
501 type->is_basic = TRUE;
502 type->tag = basic->tag;
503 type->is_pointer = basic->pointer;
505 str += strlen(basic->str);
509 /* If we're inside GLib, handle "List" etc. by prefixing with
510 * "GLib." so the parsing code below doesn't have to get more
513 if (g_str_has_prefix (str, "List<") ||
514 strcmp (str, "List") == 0)
516 temporary_type = g_strdup_printf ("GLib.List%s", str + 4);
517 str = temporary_type;
519 else if (g_str_has_prefix (str, "SList<") ||
520 strcmp (str, "SList") == 0)
522 temporary_type = g_strdup_printf ("GLib.SList%s", str + 5);
523 str = temporary_type;
525 else if (g_str_has_prefix (str, "HashTable<") ||
526 strcmp (str, "HashTable") == 0)
528 temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9);
529 str = temporary_type;
531 else if (g_str_has_prefix (str, "Error<") ||
532 strcmp (str, "Error") == 0)
534 temporary_type = g_strdup_printf ("GLib.Error%s", str + 5);
535 str = temporary_type;
540 /* found a basic type */;
541 else if (g_str_has_prefix (str, "GLib.List") ||
542 g_str_has_prefix (str, "GLib.SList"))
544 str += strlen ("GLib.");
545 if (g_str_has_prefix (str, "List"))
547 type->tag = GI_TYPE_TAG_GLIST;
548 type->is_glist = TRUE;
549 type->is_pointer = TRUE;
550 str += strlen ("List");
554 type->tag = GI_TYPE_TAG_GSLIST;
555 type->is_gslist = TRUE;
556 type->is_pointer = TRUE;
557 str += strlen ("SList");
560 else if (g_str_has_prefix (str, "GLib.HashTable"))
562 str += strlen ("GLib.");
564 type->tag = GI_TYPE_TAG_GHASH;
565 type->is_ghashtable = TRUE;
566 type->is_pointer = TRUE;
567 str += strlen ("HashTable");
569 else if (g_str_has_prefix (str, "GLib.Error"))
571 str += strlen ("GLib.");
573 type->tag = GI_TYPE_TAG_ERROR;
574 type->is_error = TRUE;
575 type->is_pointer = TRUE;
576 str += strlen ("Error");
583 end = strchr (str, '>');
584 tmp = g_strndup (str, end - str);
585 type->errors = g_strsplit (tmp, ",", 0);
594 type->tag = GI_TYPE_TAG_INTERFACE;
595 type->is_interface = TRUE;
598 /* must be an interface type */
599 while (g_ascii_isalnum (*str) ||
606 type->giinterface = g_strndup (start, str - start);
611 g_assert (type->tag >= 0 && type->tag < GI_TYPE_TAG_N_TYPES);
612 g_free (temporary_type);
616 _g_ir_node_free ((GIrNode *)type);
617 g_free (temporary_type);
622 resolve_aliases (ParseContext *ctx, const gchar *type)
626 GSList *seen_values = NULL;
630 if (strchr (type, '.') == NULL)
632 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
641 seen_values = g_slist_prepend (seen_values, (char*)lookup);
642 while (g_hash_table_lookup_extended (ctx->current_module->aliases, lookup, &orig, &value))
644 g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
646 if (g_slist_find_custom (seen_values, lookup,
647 (GCompareFunc)strcmp) != NULL)
649 seen_values = g_slist_prepend (seen_values, (gchar*)lookup);
651 g_slist_free (seen_values);
653 if (lookup == prefixed)
662 is_disguised_structure (ParseContext *ctx, const gchar *type)
668 if (strchr (type, '.') == NULL)
670 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
679 result = g_hash_table_lookup (ctx->current_module->disguised_structures,
688 parse_type (ParseContext *ctx, const gchar *type)
691 const BasicTypeInfo *basic;
692 gboolean in_glib, in_gobject;
694 in_glib = strcmp (ctx->namespace, "GLib") == 0;
695 in_gobject = strcmp (ctx->namespace, "GObject") == 0;
697 /* Do not search aliases for basic types */
698 basic = parse_basic (type);
700 type = resolve_aliases (ctx, type);
702 node = parse_type_internal (ctx->current_module, type, NULL, in_glib, in_gobject);
704 g_debug ("Parsed type: %s => %d", type, node->tag);
706 g_critical ("Failed to parse type: '%s'", type);
712 introspectable_prelude (GMarkupParseContext *context,
713 const gchar **attribute_names,
714 const gchar **attribute_values,
716 ParseState new_state)
718 const gchar *introspectable_arg;
719 const gchar *shadowed_by;
720 gboolean introspectable;
722 g_assert (ctx->state != STATE_PASSTHROUGH);
724 introspectable_arg = find_attribute ("introspectable", attribute_names, attribute_values);
725 shadowed_by = find_attribute ("shadowed-by", attribute_names, attribute_values);
727 introspectable = !(introspectable_arg && atoi (introspectable_arg) == 0) && shadowed_by == NULL;
730 state_switch (ctx, new_state);
732 state_switch (ctx, STATE_PASSTHROUGH);
734 return introspectable;
738 start_glib_boxed (GMarkupParseContext *context,
739 const gchar *element_name,
740 const gchar **attribute_names,
741 const gchar **attribute_values,
746 const gchar *typename;
747 const gchar *typeinit;
748 const gchar *deprecated;
751 if (!(strcmp (element_name, "glib:boxed") == 0 &&
752 ctx->state == STATE_NAMESPACE))
755 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_BOXED))
758 name = find_attribute ("glib:name", attribute_names, attribute_values);
759 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
760 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
761 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
765 MISSING_ATTRIBUTE (context, error, element_name, "glib:name");
768 else if (typename == NULL)
770 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
773 else if (typeinit == NULL)
775 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
779 boxed = (GIrNodeBoxed *) _g_ir_node_new (G_IR_NODE_BOXED,
780 ctx->current_module);
782 ((GIrNode *)boxed)->name = g_strdup (name);
783 boxed->gtype_name = g_strdup (typename);
784 boxed->gtype_init = g_strdup (typeinit);
786 boxed->deprecated = TRUE;
788 boxed->deprecated = FALSE;
790 push_node (ctx, (GIrNode *)boxed);
791 ctx->current_module->entries =
792 g_list_append (ctx->current_module->entries, boxed);
798 start_function (GMarkupParseContext *context,
799 const gchar *element_name,
800 const gchar **attribute_names,
801 const gchar **attribute_values,
806 const gchar *shadows;
808 const gchar *deprecated;
810 GIrNodeFunction *function;
811 gboolean found = FALSE;
812 ParseState in_embedded_state = STATE_NONE;
816 case STATE_NAMESPACE:
817 found = (strcmp (element_name, "function") == 0 ||
818 strcmp (element_name, "callback") == 0);
824 found = strcmp (element_name, "constructor") == 0;
826 case STATE_INTERFACE:
828 strcmp (element_name, "function") == 0 ||
829 strcmp (element_name, "method") == 0 ||
830 strcmp (element_name, "callback") == 0);
833 found = strcmp (element_name, "function") == 0;
835 case STATE_CLASS_FIELD:
836 case STATE_STRUCT_FIELD:
837 found = (found || strcmp (element_name, "callback") == 0);
838 in_embedded_state = ctx->state;
847 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION))
850 ctx->in_embedded_state = in_embedded_state;
852 name = find_attribute ("name", attribute_names, attribute_values);
853 shadows = find_attribute ("shadows", attribute_names, attribute_values);
854 symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
855 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
856 throws = find_attribute ("throws", attribute_names, attribute_values);
860 MISSING_ATTRIBUTE (context, error, element_name, "name");
863 else if (strcmp (element_name, "callback") != 0 && symbol == NULL)
865 MISSING_ATTRIBUTE (context, error, element_name, "c:identifier");
872 function = (GIrNodeFunction *) _g_ir_node_new (G_IR_NODE_FUNCTION,
873 ctx->current_module);
875 ((GIrNode *)function)->name = g_strdup (name);
876 function->symbol = g_strdup (symbol);
877 function->parameters = NULL;
879 function->deprecated = TRUE;
881 function->deprecated = FALSE;
883 if (strcmp (element_name, "method") == 0 ||
884 strcmp (element_name, "constructor") == 0)
886 function->is_method = TRUE;
888 if (strcmp (element_name, "constructor") == 0)
889 function->is_constructor = TRUE;
891 function->is_constructor = FALSE;
895 function->is_method = FALSE;
896 function->is_setter = FALSE;
897 function->is_getter = FALSE;
898 function->is_constructor = FALSE;
899 if (strcmp (element_name, "callback") == 0)
900 ((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
903 if (throws && strcmp (throws, "1") == 0)
904 function->throws = TRUE;
906 function->throws = FALSE;
908 if (ctx->node_stack == NULL)
910 ctx->current_module->entries =
911 g_list_append (ctx->current_module->entries, function);
913 else if (ctx->current_typed)
917 field = (GIrNodeField *)ctx->current_typed;
918 field->callback = function;
921 switch (CURRENT_NODE (ctx)->type)
923 case G_IR_NODE_INTERFACE:
924 case G_IR_NODE_OBJECT:
926 GIrNodeInterface *iface;
928 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
929 iface->members = g_list_append (iface->members, function);
932 case G_IR_NODE_BOXED:
936 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
937 boxed->members = g_list_append (boxed->members, function);
940 case G_IR_NODE_STRUCT:
942 GIrNodeStruct *struct_;
944 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
945 struct_->members = g_list_append (struct_->members, function); }
947 case G_IR_NODE_UNION:
949 GIrNodeUnion *union_;
951 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
952 union_->members = g_list_append (union_->members, function);
956 case G_IR_NODE_FLAGS:
960 enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx);
961 enum_->methods = g_list_append (enum_->methods, function);
965 g_assert_not_reached ();
968 push_node(ctx, (GIrNode *)function);
974 parse_property_transfer (GIrNodeProperty *property,
975 const gchar *transfer,
978 if (transfer == NULL)
981 GIrNodeInterface *iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
983 g_debug ("required attribute 'transfer-ownership' is missing from "
984 "property '%s' in type '%s.%s'. Assuming 'none'\n",
985 property->node.name, ctx->namespace, iface->node.name);
989 if (strcmp (transfer, "none") == 0)
991 property->transfer = FALSE;
992 property->shallow_transfer = FALSE;
994 else if (strcmp (transfer, "container") == 0)
996 property->transfer = FALSE;
997 property->shallow_transfer = TRUE;
999 else if (strcmp (transfer, "full") == 0)
1001 property->transfer = TRUE;
1002 property->shallow_transfer = FALSE;
1006 GIrNodeInterface *iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1008 g_warning ("Unknown transfer-ownership value: '%s' for property '%s' in "
1009 "type '%s.%s'", transfer, property->node.name, ctx->namespace,
1015 parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *name,
1018 if (transfer == NULL)
1020 g_set_error (error, G_MARKUP_ERROR,
1021 G_MARKUP_ERROR_INVALID_CONTENT,
1022 "required attribute 'transfer-ownership' missing");
1025 else if (strcmp (transfer, "none") == 0)
1027 param->transfer = FALSE;
1028 param->shallow_transfer = FALSE;
1030 else if (strcmp (transfer, "container") == 0)
1032 param->transfer = FALSE;
1033 param->shallow_transfer = TRUE;
1035 else if (strcmp (transfer, "full") == 0)
1037 param->transfer = TRUE;
1038 param->shallow_transfer = FALSE;
1042 g_set_error (error, G_MARKUP_ERROR,
1043 G_MARKUP_ERROR_INVALID_CONTENT,
1044 "invalid value for 'transfer-ownership': %s", transfer);
1051 start_instance_parameter (GMarkupParseContext *context,
1052 const gchar *element_name,
1053 const gchar **attribute_names,
1054 const gchar **attribute_values,
1058 const gchar *transfer;
1059 gboolean transfer_full;
1061 if (!(strcmp (element_name, "instance-parameter") == 0 &&
1062 ctx->state == STATE_FUNCTION_PARAMETERS))
1065 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1067 state_switch (ctx, STATE_PASSTHROUGH);
1069 if (g_strcmp0 (transfer, "full") == 0)
1070 transfer_full = TRUE;
1071 else if (g_strcmp0 (transfer, "none") == 0)
1072 transfer_full = FALSE;
1075 g_set_error (error, G_MARKUP_ERROR,
1076 G_MARKUP_ERROR_INVALID_CONTENT,
1077 "invalid value for 'transfer-ownership' for instance parameter: %s", transfer);
1081 switch (CURRENT_NODE (ctx)->type)
1083 case G_IR_NODE_FUNCTION:
1084 case G_IR_NODE_CALLBACK:
1086 GIrNodeFunction *func;
1088 func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1089 func->instance_transfer_full = transfer_full;
1092 case G_IR_NODE_SIGNAL:
1094 GIrNodeSignal *signal;
1096 signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
1097 signal->instance_transfer_full = transfer_full;
1100 case G_IR_NODE_VFUNC:
1102 GIrNodeVFunc *vfunc;
1104 vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1105 vfunc->instance_transfer_full = transfer_full;
1109 g_assert_not_reached ();
1116 start_parameter (GMarkupParseContext *context,
1117 const gchar *element_name,
1118 const gchar **attribute_names,
1119 const gchar **attribute_values,
1124 const gchar *direction;
1125 const gchar *retval;
1126 const gchar *optional;
1127 const gchar *caller_allocates;
1128 const gchar *allow_none;
1129 const gchar *transfer;
1131 const gchar *closure;
1132 const gchar *destroy;
1134 const gchar *nullable;
1135 GIrNodeParam *param;
1137 if (!(strcmp (element_name, "parameter") == 0 &&
1138 ctx->state == STATE_FUNCTION_PARAMETERS))
1141 name = find_attribute ("name", attribute_names, attribute_values);
1142 direction = find_attribute ("direction", attribute_names, attribute_values);
1143 retval = find_attribute ("retval", attribute_names, attribute_values);
1144 optional = find_attribute ("optional", attribute_names, attribute_values);
1145 allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
1146 caller_allocates = find_attribute ("caller-allocates", attribute_names, attribute_values);
1147 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1148 scope = find_attribute ("scope", attribute_names, attribute_values);
1149 closure = find_attribute ("closure", attribute_names, attribute_values);
1150 destroy = find_attribute ("destroy", attribute_names, attribute_values);
1151 skip = find_attribute ("skip", attribute_names, attribute_values);
1152 nullable = find_attribute ("nullable", attribute_names, attribute_values);
1157 param = (GIrNodeParam *)_g_ir_node_new (G_IR_NODE_PARAM,
1158 ctx->current_module);
1160 ctx->current_typed = (GIrNode*) param;
1161 ctx->current_typed->name = g_strdup (name);
1163 state_switch (ctx, STATE_FUNCTION_PARAMETER);
1165 if (direction && strcmp (direction, "out") == 0)
1169 if (caller_allocates == NULL)
1170 param->caller_allocates = FALSE;
1172 param->caller_allocates = strcmp (caller_allocates, "1") == 0;
1174 else if (direction && strcmp (direction, "inout") == 0)
1178 param->caller_allocates = FALSE;
1184 param->caller_allocates = FALSE;
1187 if (retval && strcmp (retval, "1") == 0)
1188 param->retval = TRUE;
1190 param->retval = FALSE;
1192 if (optional && strcmp (optional, "1") == 0)
1193 param->optional = TRUE;
1195 param->optional = FALSE;
1197 if (nullable && strcmp (nullable, "1") == 0)
1198 param->nullable = TRUE;
1200 param->nullable = FALSE;
1202 if (allow_none && strcmp (allow_none, "1") == 0)
1205 param->optional = TRUE;
1207 param->nullable = TRUE;
1210 if (skip && strcmp (skip, "1") == 0)
1213 param->skip = FALSE;
1215 if (!parse_param_transfer (param, transfer, name, error))
1218 if (scope && strcmp (scope, "call") == 0)
1219 param->scope = GI_SCOPE_TYPE_CALL;
1220 else if (scope && strcmp (scope, "async") == 0)
1221 param->scope = GI_SCOPE_TYPE_ASYNC;
1222 else if (scope && strcmp (scope, "notified") == 0)
1223 param->scope = GI_SCOPE_TYPE_NOTIFIED;
1225 param->scope = GI_SCOPE_TYPE_INVALID;
1227 param->closure = closure ? atoi (closure) : -1;
1228 param->destroy = destroy ? atoi (destroy) : -1;
1230 ((GIrNode *)param)->name = g_strdup (name);
1232 switch (CURRENT_NODE (ctx)->type)
1234 case G_IR_NODE_FUNCTION:
1235 case G_IR_NODE_CALLBACK:
1237 GIrNodeFunction *func;
1239 func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1240 func->parameters = g_list_append (func->parameters, param);
1243 case G_IR_NODE_SIGNAL:
1245 GIrNodeSignal *signal;
1247 signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
1248 signal->parameters = g_list_append (signal->parameters, param);
1251 case G_IR_NODE_VFUNC:
1253 GIrNodeVFunc *vfunc;
1255 vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1256 vfunc->parameters = g_list_append (vfunc->parameters, param);
1260 g_assert_not_reached ();
1267 start_field (GMarkupParseContext *context,
1268 const gchar *element_name,
1269 const gchar **attribute_names,
1270 const gchar **attribute_values,
1275 const gchar *readable;
1276 const gchar *writable;
1278 const gchar *branch;
1279 GIrNodeField *field;
1280 ParseState target_state;
1281 gboolean introspectable;
1286 target_state = STATE_CLASS_FIELD;
1289 target_state = STATE_BOXED_FIELD;
1292 target_state = STATE_STRUCT_FIELD;
1295 target_state = STATE_UNION_FIELD;
1297 case STATE_INTERFACE:
1298 target_state = STATE_INTERFACE_FIELD;
1304 if (strcmp (element_name, "field") != 0)
1307 g_assert (ctx->state != STATE_PASSTHROUGH);
1309 /* We handle introspectability specially here; we replace with just gpointer
1312 introspectable = introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state);
1314 name = find_attribute ("name", attribute_names, attribute_values);
1315 readable = find_attribute ("readable", attribute_names, attribute_values);
1316 writable = find_attribute ("writable", attribute_names, attribute_values);
1317 bits = find_attribute ("bits", attribute_names, attribute_values);
1318 branch = find_attribute ("branch", attribute_names, attribute_values);
1322 MISSING_ATTRIBUTE (context, error, element_name, "name");
1326 field = (GIrNodeField *)_g_ir_node_new (G_IR_NODE_FIELD,
1327 ctx->current_module);
1330 ctx->current_typed = (GIrNode*) field;
1334 field->type = parse_type (ctx, "gpointer");
1337 ((GIrNode *)field)->name = g_strdup (name);
1338 /* Fields are assumed to be read-only.
1339 * (see also girwriter.py and generate.c)
1341 field->readable = readable == NULL || strcmp (readable, "0") == 0;
1342 field->writable = writable != NULL && strcmp (writable, "1") == 0;
1345 field->bits = atoi (bits);
1349 switch (CURRENT_NODE (ctx)->type)
1351 case G_IR_NODE_OBJECT:
1353 GIrNodeInterface *iface;
1355 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1356 iface->members = g_list_append (iface->members, field);
1359 case G_IR_NODE_INTERFACE:
1361 GIrNodeInterface *iface;
1363 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1364 iface->members = g_list_append (iface->members, field);
1367 case G_IR_NODE_BOXED:
1369 GIrNodeBoxed *boxed;
1371 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
1372 boxed->members = g_list_append (boxed->members, field);
1375 case G_IR_NODE_STRUCT:
1377 GIrNodeStruct *struct_;
1379 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
1380 struct_->members = g_list_append (struct_->members, field);
1383 case G_IR_NODE_UNION:
1385 GIrNodeUnion *union_;
1387 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
1388 union_->members = g_list_append (union_->members, field);
1391 GIrNodeConstant *constant;
1393 constant = (GIrNodeConstant *) _g_ir_node_new (G_IR_NODE_CONSTANT,
1394 ctx->current_module);
1395 ((GIrNode *)constant)->name = g_strdup (name);
1396 constant->value = g_strdup (branch);
1397 constant->type = union_->discriminator_type;
1398 constant->deprecated = FALSE;
1400 union_->discriminators = g_list_append (union_->discriminators, constant);
1405 g_assert_not_reached ();
1412 start_alias (GMarkupParseContext *context,
1413 const gchar *element_name,
1414 const gchar **attribute_names,
1415 const gchar **attribute_values,
1421 name = find_attribute ("name", attribute_names, attribute_values);
1424 MISSING_ATTRIBUTE (context, error, element_name, "name");
1428 ctx->current_alias = g_strdup (name);
1429 state_switch (ctx, STATE_ALIAS);
1435 start_enum (GMarkupParseContext *context,
1436 const gchar *element_name,
1437 const gchar **attribute_names,
1438 const gchar **attribute_values,
1443 const gchar *typename;
1444 const gchar *typeinit;
1445 const gchar *deprecated;
1446 const gchar *error_domain;
1449 if (!((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
1450 (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE)))
1453 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_ENUM))
1456 name = find_attribute ("name", attribute_names, attribute_values);
1457 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1458 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1459 error_domain = find_attribute ("glib:error-domain", attribute_names, attribute_values);
1460 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1464 MISSING_ATTRIBUTE (context, error, element_name, "name");
1468 if (strcmp (element_name, "enumeration") == 0)
1469 enum_ = (GIrNodeEnum *) _g_ir_node_new (G_IR_NODE_ENUM,
1470 ctx->current_module);
1472 enum_ = (GIrNodeEnum *) _g_ir_node_new (G_IR_NODE_FLAGS,
1473 ctx->current_module);
1474 ((GIrNode *)enum_)->name = g_strdup (name);
1475 enum_->gtype_name = g_strdup (typename);
1476 enum_->gtype_init = g_strdup (typeinit);
1477 enum_->error_domain = g_strdup (error_domain);
1480 enum_->deprecated = TRUE;
1482 enum_->deprecated = FALSE;
1484 push_node (ctx, (GIrNode *) enum_);
1485 ctx->current_module->entries =
1486 g_list_append (ctx->current_module->entries, enum_);
1492 start_property (GMarkupParseContext *context,
1493 const gchar *element_name,
1494 const gchar **attribute_names,
1495 const gchar **attribute_values,
1499 ParseState target_state;
1501 const gchar *readable;
1502 const gchar *writable;
1503 const gchar *construct;
1504 const gchar *construct_only;
1505 const gchar *transfer;
1506 GIrNodeProperty *property;
1507 GIrNodeInterface *iface;
1509 if (!(strcmp (element_name, "property") == 0 &&
1510 (ctx->state == STATE_CLASS ||
1511 ctx->state == STATE_INTERFACE)))
1514 if (ctx->state == STATE_CLASS)
1515 target_state = STATE_CLASS_PROPERTY;
1516 else if (ctx->state == STATE_INTERFACE)
1517 target_state = STATE_INTERFACE_PROPERTY;
1519 g_assert_not_reached ();
1521 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state))
1525 name = find_attribute ("name", attribute_names, attribute_values);
1526 readable = find_attribute ("readable", attribute_names, attribute_values);
1527 writable = find_attribute ("writable", attribute_names, attribute_values);
1528 construct = find_attribute ("construct", attribute_names, attribute_values);
1529 construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
1530 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1534 MISSING_ATTRIBUTE (context, error, element_name, "name");
1538 property = (GIrNodeProperty *) _g_ir_node_new (G_IR_NODE_PROPERTY,
1539 ctx->current_module);
1540 ctx->current_typed = (GIrNode*) property;
1542 ((GIrNode *)property)->name = g_strdup (name);
1544 /* Assume properties are readable */
1545 if (readable == NULL || strcmp (readable, "1") == 0)
1546 property->readable = TRUE;
1548 property->readable = FALSE;
1549 if (writable && strcmp (writable, "1") == 0)
1550 property->writable = TRUE;
1552 property->writable = FALSE;
1553 if (construct && strcmp (construct, "1") == 0)
1554 property->construct = TRUE;
1556 property->construct = FALSE;
1557 if (construct_only && strcmp (construct_only, "1") == 0)
1558 property->construct_only = TRUE;
1560 property->construct_only = FALSE;
1562 parse_property_transfer (property, transfer, ctx);
1564 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1565 iface->members = g_list_append (iface->members, property);
1571 parse_value (const gchar *str)
1575 /* FIXME just a quick hack */
1576 shift_op = strstr (str, "<<");
1582 base = g_ascii_strtoll (str, NULL, 10);
1583 shift = g_ascii_strtoll (shift_op + 3, NULL, 10);
1585 return base << shift;
1588 return g_ascii_strtoll (str, NULL, 10);
1594 start_member (GMarkupParseContext *context,
1595 const gchar *element_name,
1596 const gchar **attribute_names,
1597 const gchar **attribute_values,
1603 const gchar *deprecated;
1604 const gchar *c_identifier;
1606 GIrNodeValue *value_;
1608 if (!(strcmp (element_name, "member") == 0 &&
1609 ctx->state == STATE_ENUM))
1612 name = find_attribute ("name", attribute_names, attribute_values);
1613 value = find_attribute ("value", attribute_names, attribute_values);
1614 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1615 c_identifier = find_attribute ("c:identifier", attribute_names, attribute_values);
1619 MISSING_ATTRIBUTE (context, error, element_name, "name");
1623 value_ = (GIrNodeValue *) _g_ir_node_new (G_IR_NODE_VALUE,
1624 ctx->current_module);
1626 ((GIrNode *)value_)->name = g_strdup (name);
1628 value_->value = parse_value (value);
1631 value_->deprecated = TRUE;
1633 value_->deprecated = FALSE;
1635 g_hash_table_insert (((GIrNode *)value_)->attributes,
1636 g_strdup ("c:identifier"),
1637 g_strdup (c_identifier));
1639 enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx);
1640 enum_->values = g_list_append (enum_->values, value_);
1646 start_constant (GMarkupParseContext *context,
1647 const gchar *element_name,
1648 const gchar **attribute_names,
1649 const gchar **attribute_values,
1653 ParseState prev_state;
1654 ParseState target_state;
1657 const gchar *deprecated;
1658 GIrNodeConstant *constant;
1660 if (!(strcmp (element_name, "constant") == 0 &&
1661 (ctx->state == STATE_NAMESPACE ||
1662 ctx->state == STATE_CLASS ||
1663 ctx->state == STATE_INTERFACE)))
1668 case STATE_NAMESPACE:
1669 target_state = STATE_NAMESPACE_CONSTANT;
1672 target_state = STATE_CLASS_CONSTANT;
1674 case STATE_INTERFACE:
1675 target_state = STATE_INTERFACE_CONSTANT;
1678 g_assert_not_reached ();
1681 prev_state = ctx->state;
1683 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state))
1686 name = find_attribute ("name", attribute_names, attribute_values);
1687 value = find_attribute ("value", attribute_names, attribute_values);
1688 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1692 MISSING_ATTRIBUTE (context, error, element_name, "name");
1695 else if (value == NULL)
1697 MISSING_ATTRIBUTE (context, error, element_name, "value");
1701 constant = (GIrNodeConstant *) _g_ir_node_new (G_IR_NODE_CONSTANT,
1702 ctx->current_module);
1704 ((GIrNode *)constant)->name = g_strdup (name);
1705 constant->value = g_strdup (value);
1707 ctx->current_typed = (GIrNode*) constant;
1710 constant->deprecated = TRUE;
1712 constant->deprecated = FALSE;
1714 if (prev_state == STATE_NAMESPACE)
1716 push_node (ctx, (GIrNode *) constant);
1717 ctx->current_module->entries =
1718 g_list_append (ctx->current_module->entries, constant);
1722 GIrNodeInterface *iface;
1724 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1725 iface->members = g_list_append (iface->members, constant);
1732 start_interface (GMarkupParseContext *context,
1733 const gchar *element_name,
1734 const gchar **attribute_names,
1735 const gchar **attribute_values,
1740 const gchar *typename;
1741 const gchar *typeinit;
1742 const gchar *deprecated;
1743 const gchar *glib_type_struct;
1744 GIrNodeInterface *iface;
1746 if (!(strcmp (element_name, "interface") == 0 &&
1747 ctx->state == STATE_NAMESPACE))
1750 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_INTERFACE))
1753 name = find_attribute ("name", attribute_names, attribute_values);
1754 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1755 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1756 glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values);
1757 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1761 MISSING_ATTRIBUTE (context, error, element_name, "name");
1764 else if (typename == NULL)
1766 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1769 else if (typeinit == NULL)
1771 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1775 iface = (GIrNodeInterface *) _g_ir_node_new (G_IR_NODE_INTERFACE,
1776 ctx->current_module);
1777 ((GIrNode *)iface)->name = g_strdup (name);
1778 iface->gtype_name = g_strdup (typename);
1779 iface->gtype_init = g_strdup (typeinit);
1780 iface->glib_type_struct = g_strdup (glib_type_struct);
1782 iface->deprecated = TRUE;
1784 iface->deprecated = FALSE;
1786 push_node (ctx, (GIrNode *) iface);
1787 ctx->current_module->entries =
1788 g_list_append (ctx->current_module->entries, iface);
1794 start_class (GMarkupParseContext *context,
1795 const gchar *element_name,
1796 const gchar **attribute_names,
1797 const gchar **attribute_values,
1802 const gchar *parent;
1803 const gchar *glib_type_struct;
1804 const gchar *typename;
1805 const gchar *typeinit;
1806 const gchar *deprecated;
1807 const gchar *abstract;
1808 const gchar *fundamental;
1809 const gchar *ref_func;
1810 const gchar *unref_func;
1811 const gchar *set_value_func;
1812 const gchar *get_value_func;
1813 GIrNodeInterface *iface;
1815 if (!(strcmp (element_name, "class") == 0 &&
1816 ctx->state == STATE_NAMESPACE))
1819 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_CLASS))
1822 name = find_attribute ("name", attribute_names, attribute_values);
1823 parent = find_attribute ("parent", attribute_names, attribute_values);
1824 glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values);
1825 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1826 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1827 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1828 abstract = find_attribute ("abstract", attribute_names, attribute_values);
1829 fundamental = find_attribute ("glib:fundamental", attribute_names, attribute_values);
1830 ref_func = find_attribute ("glib:ref-func", attribute_names, attribute_values);
1831 unref_func = find_attribute ("glib:unref-func", attribute_names, attribute_values);
1832 set_value_func = find_attribute ("glib:set-value-func", attribute_names, attribute_values);
1833 get_value_func = find_attribute ("glib:get-value-func", attribute_names, attribute_values);
1837 MISSING_ATTRIBUTE (context, error, element_name, "name");
1840 else if (typename == NULL)
1842 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1845 else if (typeinit == NULL && strcmp (typename, "GObject"))
1847 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1851 iface = (GIrNodeInterface *) _g_ir_node_new (G_IR_NODE_OBJECT,
1852 ctx->current_module);
1853 ((GIrNode *)iface)->name = g_strdup (name);
1854 iface->gtype_name = g_strdup (typename);
1855 iface->gtype_init = g_strdup (typeinit);
1856 iface->parent = g_strdup (parent);
1857 iface->glib_type_struct = g_strdup (glib_type_struct);
1859 iface->deprecated = TRUE;
1861 iface->deprecated = FALSE;
1863 iface->abstract = abstract && strcmp (abstract, "1") == 0;
1866 iface->fundamental = TRUE;
1868 iface->ref_func = g_strdup (ref_func);
1870 iface->unref_func = g_strdup (unref_func);
1872 iface->set_value_func = g_strdup (set_value_func);
1874 iface->get_value_func = g_strdup (get_value_func);
1876 push_node (ctx, (GIrNode *) iface);
1877 ctx->current_module->entries =
1878 g_list_append (ctx->current_module->entries, iface);
1884 start_type (GMarkupParseContext *context,
1885 const gchar *element_name,
1886 const gchar **attribute_names,
1887 const gchar **attribute_values,
1893 gboolean in_alias = FALSE;
1895 gboolean is_varargs;
1896 GIrNodeType *typenode;
1898 is_array = strcmp (element_name, "array") == 0;
1899 is_varargs = strcmp (element_name, "varargs") == 0;
1901 if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
1904 if (ctx->state == STATE_TYPE)
1907 ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters);
1908 ctx->type_parameters = NULL;
1910 else if (ctx->state == STATE_FUNCTION_PARAMETER ||
1911 ctx->state == STATE_FUNCTION_RETURN ||
1912 ctx->state == STATE_STRUCT_FIELD ||
1913 ctx->state == STATE_UNION_FIELD ||
1914 ctx->state == STATE_CLASS_PROPERTY ||
1915 ctx->state == STATE_CLASS_FIELD ||
1916 ctx->state == STATE_INTERFACE_FIELD ||
1917 ctx->state == STATE_INTERFACE_PROPERTY ||
1918 ctx->state == STATE_BOXED_FIELD ||
1919 ctx->state == STATE_NAMESPACE_CONSTANT ||
1920 ctx->state == STATE_CLASS_CONSTANT ||
1921 ctx->state == STATE_INTERFACE_CONSTANT ||
1922 ctx->state == STATE_ALIAS
1925 if (ctx->state == STATE_ALIAS)
1927 state_switch (ctx, STATE_TYPE);
1928 ctx->type_depth = 1;
1929 ctx->type_stack = NULL;
1930 ctx->type_parameters = NULL;
1933 name = find_attribute ("name", attribute_names, attribute_values);
1935 if (in_alias && ctx->current_alias)
1942 MISSING_ATTRIBUTE (context, error, element_name, "name");
1946 key = g_strdup_printf ("%s.%s", ctx->namespace, ctx->current_alias);
1947 if (!strchr (name, '.'))
1949 const BasicTypeInfo *basic = parse_basic (name);
1952 /* For non-basic types, re-qualify the interface */
1953 value = g_strdup_printf ("%s.%s", ctx->namespace, name);
1957 value = g_strdup (name);
1961 value = g_strdup (name);
1963 g_hash_table_replace (ctx->aliases, key, value);
1967 else if (!ctx->current_module || in_alias)
1970 if (!ctx->current_typed)
1974 G_MARKUP_ERROR_INVALID_CONTENT,
1975 "The element <type> is invalid here");
1988 typenode = (GIrNodeType *)_g_ir_node_new (G_IR_NODE_TYPE,
1989 ctx->current_module);
1991 typenode->tag = GI_TYPE_TAG_ARRAY;
1992 typenode->is_pointer = TRUE;
1993 typenode->is_array = TRUE;
1995 if (name && strcmp (name, "GLib.Array") == 0) {
1996 typenode->array_type = GI_ARRAY_TYPE_ARRAY;
1997 } else if (name && strcmp (name, "GLib.ByteArray") == 0) {
1998 typenode->array_type = GI_ARRAY_TYPE_BYTE_ARRAY;
1999 } else if (name && strcmp (name, "GLib.PtrArray") == 0) {
2000 typenode->array_type = GI_ARRAY_TYPE_PTR_ARRAY;
2002 typenode->array_type = GI_ARRAY_TYPE_C;
2005 if (typenode->array_type == GI_ARRAY_TYPE_C) {
2006 zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
2007 len = find_attribute ("length", attribute_names, attribute_values);
2008 size = find_attribute ("fixed-size", attribute_names, attribute_values);
2010 typenode->has_length = len != NULL;
2011 typenode->length = typenode->has_length ? atoi (len) : -1;
2013 typenode->has_size = size != NULL;
2014 typenode->size = typenode->has_size ? atoi (size) : -1;
2017 typenode->zero_terminated = strcmp(zero, "1") == 0;
2019 /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */
2020 typenode->zero_terminated = !(typenode->has_length || typenode->has_size);
2022 if (typenode->has_size && ctx->current_typed->type == G_IR_NODE_FIELD)
2023 typenode->is_pointer = FALSE;
2025 typenode->zero_terminated = FALSE;
2026 typenode->has_length = FALSE;
2027 typenode->length = -1;
2028 typenode->has_size = FALSE;
2029 typenode->size = -1;
2038 MISSING_ATTRIBUTE (context, error, element_name, "name");
2043 ctype = find_attribute ("c:type", attribute_names, attribute_values);
2046 const char *cp = ctype + strlen(ctype) - 1;
2047 while (cp > ctype && *cp-- == '*')
2050 if (g_str_has_prefix (ctype, "gpointer")
2051 || g_str_has_prefix (ctype, "gconstpointer"))
2055 if (ctx->current_typed->type == G_IR_NODE_PARAM &&
2056 ((GIrNodeParam *)ctx->current_typed)->out &&
2060 typenode = parse_type (ctx, name);
2062 /* A 'disguised' structure is one where the c:type is a typedef that
2063 * doesn't look like a pointer, but is internally.
2065 if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
2066 is_disguised_structure (ctx, typenode->giinterface))
2069 if (pointer_depth > 0)
2070 typenode->is_pointer = TRUE;
2073 ctx->type_parameters = g_list_append (ctx->type_parameters, typenode);
2079 end_type_top (ParseContext *ctx)
2081 GIrNodeType *typenode;
2083 if (!ctx->type_parameters)
2086 typenode = (GIrNodeType*)ctx->type_parameters->data;
2088 /* Default to pointer for unspecified containers */
2089 if (typenode->tag == GI_TYPE_TAG_ARRAY ||
2090 typenode->tag == GI_TYPE_TAG_GLIST ||
2091 typenode->tag == GI_TYPE_TAG_GSLIST)
2093 if (typenode->parameter_type1 == NULL)
2094 typenode->parameter_type1 = parse_type (ctx, "gpointer");
2096 else if (typenode->tag == GI_TYPE_TAG_GHASH)
2098 if (typenode->parameter_type1 == NULL)
2100 typenode->parameter_type1 = parse_type (ctx, "gpointer");
2101 typenode->parameter_type2 = parse_type (ctx, "gpointer");
2105 switch (ctx->current_typed->type)
2107 case G_IR_NODE_PARAM:
2109 GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed;
2110 param->type = typenode;
2113 case G_IR_NODE_FIELD:
2115 GIrNodeField *field = (GIrNodeField *)ctx->current_typed;
2116 field->type = typenode;
2119 case G_IR_NODE_PROPERTY:
2121 GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed;
2122 property->type = typenode;
2125 case G_IR_NODE_CONSTANT:
2127 GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed;
2128 constant->type = typenode;
2132 g_printerr("current node is %d\n", CURRENT_NODE (ctx)->type);
2133 g_assert_not_reached ();
2135 g_list_free (ctx->type_parameters);
2138 ctx->type_depth = 0;
2139 ctx->type_parameters = NULL;
2140 ctx->current_typed = NULL;
2144 end_type_recurse (ParseContext *ctx)
2146 GIrNodeType *parent;
2147 GIrNodeType *param = NULL;
2149 parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data;
2150 if (ctx->type_parameters)
2151 param = (GIrNodeType *) ctx->type_parameters->data;
2153 if (parent->tag == GI_TYPE_TAG_ARRAY ||
2154 parent->tag == GI_TYPE_TAG_GLIST ||
2155 parent->tag == GI_TYPE_TAG_GSLIST)
2157 g_assert (param != NULL);
2159 if (parent->parameter_type1 == NULL)
2160 parent->parameter_type1 = param;
2162 g_assert_not_reached ();
2164 else if (parent->tag == GI_TYPE_TAG_GHASH)
2166 g_assert (param != NULL);
2168 if (parent->parameter_type1 == NULL)
2169 parent->parameter_type1 = param;
2170 else if (parent->parameter_type2 == NULL)
2171 parent->parameter_type2 = param;
2173 g_assert_not_reached ();
2175 g_list_free (ctx->type_parameters);
2176 ctx->type_parameters = (GList *)ctx->type_stack->data;
2177 ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
2181 end_type (ParseContext *ctx)
2183 if (ctx->type_depth == 1)
2186 state_switch (ctx, ctx->prev_state);
2190 end_type_recurse (ctx);
2196 start_attribute (GMarkupParseContext *context,
2197 const gchar *element_name,
2198 const gchar **attribute_names,
2199 const gchar **attribute_values,
2207 if (strcmp (element_name, "attribute") != 0 || ctx->node_stack == NULL)
2210 name = find_attribute ("name", attribute_names, attribute_values);
2211 value = find_attribute ("value", attribute_names, attribute_values);
2215 MISSING_ATTRIBUTE (context, error, element_name, "name");
2220 MISSING_ATTRIBUTE (context, error, element_name, "value");
2224 state_switch (ctx, STATE_ATTRIBUTE);
2226 curnode = CURRENT_NODE (ctx);
2228 if (ctx->current_typed && ctx->current_typed->type == G_IR_NODE_PARAM)
2230 g_hash_table_insert (ctx->current_typed->attributes, g_strdup (name), g_strdup (value));
2234 g_hash_table_insert (curnode->attributes, g_strdup (name), g_strdup (value));
2241 start_return_value (GMarkupParseContext *context,
2242 const gchar *element_name,
2243 const gchar **attribute_names,
2244 const gchar **attribute_values,
2248 GIrNodeParam *param;
2249 const gchar *transfer;
2251 const gchar *nullable;
2253 if (!(strcmp (element_name, "return-value") == 0 &&
2254 ctx->state == STATE_FUNCTION))
2257 param = (GIrNodeParam *)_g_ir_node_new (G_IR_NODE_PARAM,
2258 ctx->current_module);
2261 param->retval = TRUE;
2263 ctx->current_typed = (GIrNode*) param;
2265 state_switch (ctx, STATE_FUNCTION_RETURN);
2267 skip = find_attribute ("skip", attribute_names, attribute_values);
2268 if (skip && strcmp (skip, "1") == 0)
2271 param->skip = FALSE;
2273 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
2274 if (!parse_param_transfer (param, transfer, NULL, error))
2277 nullable = find_attribute ("nullable", attribute_names, attribute_values);
2278 if (nullable && g_str_equal (nullable, "1"))
2279 param->nullable = TRUE;
2281 switch (CURRENT_NODE (ctx)->type)
2283 case G_IR_NODE_FUNCTION:
2284 case G_IR_NODE_CALLBACK:
2286 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
2287 func->result = param;
2290 case G_IR_NODE_SIGNAL:
2292 GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
2293 signal->result = param;
2296 case G_IR_NODE_VFUNC:
2298 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
2299 vfunc->result = param;
2303 g_assert_not_reached ();
2310 start_implements (GMarkupParseContext *context,
2311 const gchar *element_name,
2312 const gchar **attribute_names,
2313 const gchar **attribute_values,
2317 GIrNodeInterface *iface;
2320 if (strcmp (element_name, "implements") != 0 ||
2321 !(ctx->state == STATE_CLASS))
2324 state_switch (ctx, STATE_IMPLEMENTS);
2326 name = find_attribute ("name", attribute_names, attribute_values);
2329 MISSING_ATTRIBUTE (context, error, element_name, "name");
2333 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2334 iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
2340 start_glib_signal (GMarkupParseContext *context,
2341 const gchar *element_name,
2342 const gchar **attribute_names,
2343 const gchar **attribute_values,
2349 const gchar *no_recurse;
2350 const gchar *detailed;
2351 const gchar *action;
2352 const gchar *no_hooks;
2353 const gchar *has_class_closure;
2354 GIrNodeInterface *iface;
2355 GIrNodeSignal *signal;
2357 if (!(strcmp (element_name, "glib:signal") == 0 &&
2358 (ctx->state == STATE_CLASS ||
2359 ctx->state == STATE_INTERFACE)))
2362 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION))
2365 name = find_attribute ("name", attribute_names, attribute_values);
2366 when = find_attribute ("when", attribute_names, attribute_values);
2367 no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values);
2368 detailed = find_attribute ("detailed", attribute_names, attribute_values);
2369 action = find_attribute ("action", attribute_names, attribute_values);
2370 no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values);
2371 has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values);
2375 MISSING_ATTRIBUTE (context, error, element_name, "name");
2378 signal = (GIrNodeSignal *)_g_ir_node_new (G_IR_NODE_SIGNAL,
2379 ctx->current_module);
2381 ((GIrNode *)signal)->name = g_strdup (name);
2383 signal->run_first = FALSE;
2384 signal->run_last = FALSE;
2385 signal->run_cleanup = FALSE;
2386 if (when == NULL || g_ascii_strcasecmp (when, "LAST") == 0)
2387 signal->run_last = TRUE;
2388 else if (g_ascii_strcasecmp (when, "FIRST") == 0)
2389 signal->run_first = TRUE;
2391 signal->run_cleanup = TRUE;
2393 if (no_recurse && strcmp (no_recurse, "1") == 0)
2394 signal->no_recurse = TRUE;
2396 signal->no_recurse = FALSE;
2397 if (detailed && strcmp (detailed, "1") == 0)
2398 signal->detailed = TRUE;
2400 signal->detailed = FALSE;
2401 if (action && strcmp (action, "1") == 0)
2402 signal->action = TRUE;
2404 signal->action = FALSE;
2405 if (no_hooks && strcmp (no_hooks, "1") == 0)
2406 signal->no_hooks = TRUE;
2408 signal->no_hooks = FALSE;
2409 if (has_class_closure && strcmp (has_class_closure, "1") == 0)
2410 signal->has_class_closure = TRUE;
2412 signal->has_class_closure = FALSE;
2414 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2415 iface->members = g_list_append (iface->members, signal);
2417 push_node (ctx, (GIrNode *)signal);
2423 start_vfunc (GMarkupParseContext *context,
2424 const gchar *element_name,
2425 const gchar **attribute_names,
2426 const gchar **attribute_values,
2431 const gchar *must_chain_up;
2432 const gchar *override;
2433 const gchar *is_class_closure;
2434 const gchar *offset;
2435 const gchar *invoker;
2436 const gchar *throws;
2437 GIrNodeInterface *iface;
2438 GIrNodeVFunc *vfunc;
2440 if (!(strcmp (element_name, "virtual-method") == 0 &&
2441 (ctx->state == STATE_CLASS ||
2442 ctx->state == STATE_INTERFACE)))
2445 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION))
2448 name = find_attribute ("name", attribute_names, attribute_values);
2449 must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values);
2450 override = find_attribute ("override", attribute_names, attribute_values);
2451 is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values);
2452 offset = find_attribute ("offset", attribute_names, attribute_values);
2453 invoker = find_attribute ("invoker", attribute_names, attribute_values);
2454 throws = find_attribute ("throws", attribute_names, attribute_values);
2458 MISSING_ATTRIBUTE (context, error, element_name, "name");
2462 vfunc = (GIrNodeVFunc *)_g_ir_node_new (G_IR_NODE_VFUNC,
2463 ctx->current_module);
2465 ((GIrNode *)vfunc)->name = g_strdup (name);
2467 if (must_chain_up && strcmp (must_chain_up, "1") == 0)
2468 vfunc->must_chain_up = TRUE;
2470 vfunc->must_chain_up = FALSE;
2472 if (override && strcmp (override, "always") == 0)
2474 vfunc->must_be_implemented = TRUE;
2475 vfunc->must_not_be_implemented = FALSE;
2477 else if (override && strcmp (override, "never") == 0)
2479 vfunc->must_be_implemented = FALSE;
2480 vfunc->must_not_be_implemented = TRUE;
2484 vfunc->must_be_implemented = FALSE;
2485 vfunc->must_not_be_implemented = FALSE;
2488 if (is_class_closure && strcmp (is_class_closure, "1") == 0)
2489 vfunc->is_class_closure = TRUE;
2491 vfunc->is_class_closure = FALSE;
2493 if (throws && strcmp (throws, "1") == 0)
2494 vfunc->throws = TRUE;
2496 vfunc->throws = FALSE;
2499 vfunc->offset = atoi (offset);
2501 vfunc->offset = 0xFFFF;
2503 vfunc->invoker = g_strdup (invoker);
2505 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2506 iface->members = g_list_append (iface->members, vfunc);
2508 push_node (ctx, (GIrNode *)vfunc);
2514 start_struct (GMarkupParseContext *context,
2515 const gchar *element_name,
2516 const gchar **attribute_names,
2517 const gchar **attribute_values,
2522 const gchar *deprecated;
2523 const gchar *disguised;
2524 const gchar *gtype_name;
2525 const gchar *gtype_init;
2526 const gchar *gtype_struct;
2527 const gchar *foreign;
2528 GIrNodeStruct *struct_;
2530 if (!(strcmp (element_name, "record") == 0 &&
2531 (ctx->state == STATE_NAMESPACE ||
2532 ctx->state == STATE_UNION ||
2533 ctx->state == STATE_STRUCT ||
2534 ctx->state == STATE_CLASS)))
2537 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_STRUCT))
2540 name = find_attribute ("name", attribute_names, attribute_values);
2541 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2542 disguised = find_attribute ("disguised", attribute_names, attribute_values);
2543 gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
2544 gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
2545 gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values);
2546 foreign = find_attribute ("foreign", attribute_names, attribute_values);
2548 if (name == NULL && ctx->node_stack == NULL)
2550 MISSING_ATTRIBUTE (context, error, element_name, "name");
2553 if ((gtype_name == NULL && gtype_init != NULL))
2555 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
2558 if ((gtype_name != NULL && gtype_init == NULL))
2560 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
2564 struct_ = (GIrNodeStruct *) _g_ir_node_new (G_IR_NODE_STRUCT,
2565 ctx->current_module);
2567 ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
2569 struct_->deprecated = TRUE;
2571 struct_->deprecated = FALSE;
2573 if (disguised && strcmp (disguised, "1") == 0)
2574 struct_->disguised = TRUE;
2576 struct_->is_gtype_struct = gtype_struct != NULL;
2578 struct_->gtype_name = g_strdup (gtype_name);
2579 struct_->gtype_init = g_strdup (gtype_init);
2581 struct_->foreign = (g_strcmp0 (foreign, "1") == 0);
2583 if (ctx->node_stack == NULL)
2584 ctx->current_module->entries =
2585 g_list_append (ctx->current_module->entries, struct_);
2586 push_node (ctx, (GIrNode *)struct_);
2591 start_union (GMarkupParseContext *context,
2592 const gchar *element_name,
2593 const gchar **attribute_names,
2594 const gchar **attribute_values,
2599 const gchar *deprecated;
2600 const gchar *typename;
2601 const gchar *typeinit;
2602 GIrNodeUnion *union_;
2604 if (!(strcmp (element_name, "union") == 0 &&
2605 (ctx->state == STATE_NAMESPACE ||
2606 ctx->state == STATE_UNION ||
2607 ctx->state == STATE_STRUCT ||
2608 ctx->state == STATE_CLASS)))
2611 if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_UNION))
2614 name = find_attribute ("name", attribute_names, attribute_values);
2615 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2616 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
2617 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
2619 if (name == NULL && ctx->node_stack == NULL)
2621 MISSING_ATTRIBUTE (context, error, element_name, "name");
2625 union_ = (GIrNodeUnion *) _g_ir_node_new (G_IR_NODE_UNION,
2626 ctx->current_module);
2628 ((GIrNode *)union_)->name = g_strdup (name ? name : "");
2629 union_->gtype_name = g_strdup (typename);
2630 union_->gtype_init = g_strdup (typeinit);
2632 union_->deprecated = TRUE;
2634 union_->deprecated = FALSE;
2636 if (ctx->node_stack == NULL)
2637 ctx->current_module->entries =
2638 g_list_append (ctx->current_module->entries, union_);
2639 push_node (ctx, (GIrNode *)union_);
2644 start_discriminator (GMarkupParseContext *context,
2645 const gchar *element_name,
2646 const gchar **attribute_names,
2647 const gchar **attribute_values,
2652 const gchar *offset;
2653 if (!(strcmp (element_name, "discriminator") == 0 &&
2654 ctx->state == STATE_UNION))
2657 type = find_attribute ("type", attribute_names, attribute_values);
2658 offset = find_attribute ("offset", attribute_names, attribute_values);
2661 MISSING_ATTRIBUTE (context, error, element_name, "type");
2664 else if (offset == NULL)
2666 MISSING_ATTRIBUTE (context, error, element_name, "offset");
2670 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type
2671 = parse_type (ctx, type);
2672 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset
2679 parse_include (GMarkupParseContext *context,
2682 const char *version)
2684 GError *error = NULL;
2687 gchar *girpath, *girname;
2691 for (l = ctx->parser->parsed_modules; l; l = l->next)
2693 GIrModule *m = l->data;
2695 if (strcmp (m->name, name) == 0)
2697 if (strcmp (m->version, version) == 0)
2699 ctx->include_modules = g_list_prepend (ctx->include_modules, m);
2705 g_printerr ("Module '%s' imported with conflicting versions '%s' and '%s'\n",
2706 name, m->version, version);
2712 girname = g_strdup_printf ("%s-%s.gir", name, version);
2713 girpath = locate_gir (ctx->parser, girname);
2715 if (girpath == NULL)
2717 g_printerr ("Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir\n",
2724 g_debug ("Parsing include %s\n", girpath);
2726 if (!g_file_get_contents (girpath, &buffer, &length, &error))
2728 g_printerr ("%s: %s\n", girpath, error->message);
2729 g_clear_error (&error);
2734 module = _g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error);
2738 int line_number, char_number;
2739 g_markup_parse_context_get_position (context, &line_number, &char_number);
2740 g_printerr ("%s:%d:%d: error: %s\n", girpath, line_number, char_number, error->message);
2741 g_clear_error (&error);
2747 ctx->include_modules = g_list_append (ctx->include_modules,
2753 extern GLogLevelFlags logged_levels;
2756 start_element_handler (GMarkupParseContext *context,
2757 const gchar *element_name,
2758 const gchar **attribute_names,
2759 const gchar **attribute_values,
2763 ParseContext *ctx = user_data;
2765 if (logged_levels & G_LOG_LEVEL_DEBUG)
2767 GString *tags = g_string_new ("");
2769 for (i = 0; attribute_names[i]; i++)
2770 g_string_append_printf (tags, "%s=\"%s\" ",
2772 attribute_values[i]);
2776 g_string_insert_c (tags, 0, ' ');
2777 g_string_truncate (tags, tags->len - 1);
2779 g_debug ("<%s%s>", element_name, tags->str);
2780 g_string_free (tags, TRUE);
2783 if (ctx->state == STATE_PASSTHROUGH)
2785 ctx->unknown_depth += 1;
2789 switch (element_name[0])
2792 if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0)
2794 state_switch (ctx, STATE_ALIAS);
2797 if (start_type (context, element_name,
2798 attribute_names, attribute_values,
2801 else if (start_attribute (context, element_name,
2802 attribute_names, attribute_values,
2807 if (start_enum (context, element_name,
2808 attribute_names, attribute_values,
2813 if (start_function (context, element_name,
2814 attribute_names, attribute_values,
2817 else if (start_constant (context, element_name,
2818 attribute_names, attribute_values,
2821 else if (start_class (context, element_name,
2822 attribute_names, attribute_values,
2828 if (start_discriminator (context, element_name,
2829 attribute_names, attribute_values,
2832 if (strcmp ("doc", element_name) == 0 || strcmp ("doc-deprecated", element_name) == 0 ||
2833 strcmp ("doc-stability", element_name) == 0 || strcmp ("doc-version", element_name) == 0)
2835 state_switch (ctx, STATE_PASSTHROUGH);
2841 if (start_enum (context, element_name,
2842 attribute_names, attribute_values,
2848 if (strcmp ("function-macro", element_name) == 0)
2850 state_switch (ctx, STATE_PASSTHROUGH);
2853 else if (start_function (context, element_name,
2854 attribute_names, attribute_values,
2857 else if (start_field (context, element_name,
2858 attribute_names, attribute_values,
2864 if (start_glib_boxed (context, element_name,
2865 attribute_names, attribute_values,
2868 else if (start_glib_signal (context, element_name,
2869 attribute_names, attribute_values,
2875 if (strcmp (element_name, "include") == 0 &&
2876 ctx->state == STATE_REPOSITORY)
2879 const gchar *version;
2881 name = find_attribute ("name", attribute_names, attribute_values);
2882 version = find_attribute ("version", attribute_names, attribute_values);
2886 MISSING_ATTRIBUTE (context, error, element_name, "name");
2889 if (version == NULL)
2891 MISSING_ATTRIBUTE (context, error, element_name, "version");
2895 if (!parse_include (context, ctx, name, version))
2899 G_MARKUP_ERROR_INVALID_CONTENT,
2900 "Failed to parse included gir %s-%s",
2906 ctx->dependencies = g_list_prepend (ctx->dependencies,
2907 g_strdup_printf ("%s-%s", name, version));
2910 state_switch (ctx, STATE_INCLUDE);
2913 if (start_interface (context, element_name,
2914 attribute_names, attribute_values,
2917 else if (start_implements (context, element_name,
2918 attribute_names, attribute_values,
2921 else if (start_instance_parameter (context, element_name,
2922 attribute_names, attribute_values,
2925 else if (strcmp (element_name, "c:include") == 0)
2927 state_switch (ctx, STATE_C_INCLUDE);
2933 if (start_function (context, element_name,
2934 attribute_names, attribute_values,
2937 else if (start_member (context, element_name,
2938 attribute_names, attribute_values,
2944 if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2946 const gchar *name, *version, *shared_library, *cprefix;
2948 if (ctx->current_module != NULL)
2952 G_MARKUP_ERROR_INVALID_CONTENT,
2953 "Only one <namespace/> element is currently allowed per <repository/>");
2957 name = find_attribute ("name", attribute_names, attribute_values);
2958 version = find_attribute ("version", attribute_names, attribute_values);
2959 shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2960 cprefix = find_attribute ("c:identifier-prefixes", attribute_names, attribute_values);
2961 /* Backwards compatibility; vala currently still generates this */
2962 if (cprefix == NULL)
2963 cprefix = find_attribute ("c:prefix", attribute_names, attribute_values);
2966 MISSING_ATTRIBUTE (context, error, element_name, "name");
2967 else if (version == NULL)
2968 MISSING_ATTRIBUTE (context, error, element_name, "version");
2973 if (strcmp (name, ctx->namespace) != 0)
2976 G_MARKUP_ERROR_INVALID_CONTENT,
2977 "<namespace/> name element '%s' doesn't match file name '%s'",
2978 name, ctx->namespace);
2980 ctx->current_module = _g_ir_module_new (name, version, shared_library, cprefix);
2982 ctx->current_module->aliases = ctx->aliases;
2983 ctx->aliases = NULL;
2984 ctx->current_module->disguised_structures = ctx->disguised_structures;
2985 ctx->disguised_structures = NULL;
2987 for (l = ctx->include_modules; l; l = l->next)
2988 _g_ir_module_add_include_module (ctx->current_module, l->data);
2990 g_list_free (ctx->include_modules);
2991 ctx->include_modules = NULL;
2993 ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2994 ctx->current_module->dependencies = ctx->dependencies;
2996 state_switch (ctx, STATE_NAMESPACE);
3003 if (start_property (context, element_name,
3004 attribute_names, attribute_values,
3007 else if (strcmp (element_name, "parameters") == 0 &&
3008 ctx->state == STATE_FUNCTION)
3010 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
3014 else if (start_parameter (context, element_name,
3015 attribute_names, attribute_values,
3018 else if (strcmp (element_name, "prerequisite") == 0 &&
3019 ctx->state == STATE_INTERFACE)
3023 name = find_attribute ("name", attribute_names, attribute_values);
3025 state_switch (ctx, STATE_PREREQUISITE);
3028 MISSING_ATTRIBUTE (context, error, element_name, "name");
3031 GIrNodeInterface *iface;
3033 iface = (GIrNodeInterface *)CURRENT_NODE(ctx);
3034 iface->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
3038 else if (strcmp (element_name, "package") == 0 &&
3039 ctx->state == STATE_REPOSITORY)
3041 state_switch (ctx, STATE_PACKAGE);
3047 if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
3049 const gchar *version;
3051 version = find_attribute ("version", attribute_names, attribute_values);
3053 if (version == NULL)
3054 MISSING_ATTRIBUTE (context, error, element_name, "version");
3055 else if (strcmp (version, SUPPORTED_GIR_VERSION) != 0)
3058 G_MARKUP_ERROR_INVALID_CONTENT,
3059 "Unsupported version '%s'",
3062 state_switch (ctx, STATE_REPOSITORY);
3066 else if (start_return_value (context, element_name,
3067 attribute_names, attribute_values,
3070 else if (start_struct (context, element_name,
3071 attribute_names, attribute_values,
3077 if (strcmp ("source-position", element_name) == 0)
3079 state_switch (ctx, STATE_PASSTHROUGH);
3084 if (start_union (context, element_name,
3085 attribute_names, attribute_values,
3091 if (start_type (context, element_name,
3092 attribute_names, attribute_values,
3098 if (start_vfunc (context, element_name,
3099 attribute_names, attribute_values,
3102 if (start_type (context, element_name,
3103 attribute_names, attribute_values,
3111 if (*error == NULL && ctx->state != STATE_PASSTHROUGH)
3113 gint line_number, char_number;
3114 g_markup_parse_context_get_position (context, &line_number, &char_number);
3115 if (!g_str_has_prefix (element_name, "c:"))
3116 g_printerr ("%s:%d:%d: warning: element %s from state %d is unknown, ignoring\n",
3117 ctx->file_path, line_number, char_number, element_name,
3119 state_switch (ctx, STATE_PASSTHROUGH);
3125 gint line_number, char_number;
3126 g_markup_parse_context_get_position (context, &line_number, &char_number);
3128 g_printerr ("%s:%d:%d: error: %s\n", ctx->file_path, line_number, char_number, (*error)->message);
3133 require_one_of_end_elements (GMarkupParseContext *context,
3135 const char *actual_name,
3140 int line_number, char_number;
3141 const char *expected;
3142 gboolean matched = FALSE;
3144 va_start (args, error);
3146 while ((expected = va_arg (args, const char*)) != NULL)
3148 if (strcmp (expected, actual_name) == 0)
3160 g_markup_parse_context_get_position (context, &line_number, &char_number);
3163 G_MARKUP_ERROR_INVALID_CONTENT,
3164 "Unexpected end tag '%s' on line %d char %d; current state=%d (prev=%d)",
3166 line_number, char_number, ctx->state, ctx->prev_state);
3171 state_switch_end_struct_or_union (GMarkupParseContext *context,
3173 const gchar *element_name,
3177 if (ctx->node_stack == NULL)
3179 state_switch (ctx, STATE_NAMESPACE);
3183 if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
3184 state_switch (ctx, STATE_STRUCT);
3185 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
3186 state_switch (ctx, STATE_UNION);
3187 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
3188 state_switch (ctx, STATE_CLASS);
3191 int line_number, char_number;
3192 g_markup_parse_context_get_position (context, &line_number, &char_number);
3195 G_MARKUP_ERROR_INVALID_CONTENT,
3196 "Unexpected end tag '%s' on line %d char %d",
3198 line_number, char_number);
3206 require_end_element (GMarkupParseContext *context,
3208 const char *expected_name,
3209 const char *actual_name,
3212 return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
3216 end_element_handler (GMarkupParseContext *context,
3217 const gchar *element_name,
3221 ParseContext *ctx = user_data;
3223 g_debug ("</%s>", element_name);
3229 /* no need to GError here, GMarkup already catches this */
3232 case STATE_REPOSITORY:
3233 state_switch (ctx, STATE_END);
3237 if (require_end_element (context, ctx, "include", element_name, error))
3239 state_switch (ctx, STATE_REPOSITORY);
3243 case STATE_C_INCLUDE:
3244 if (require_end_element (context, ctx, "c:include", element_name, error))
3246 state_switch (ctx, STATE_REPOSITORY);
3251 if (require_end_element (context, ctx, "package", element_name, error))
3253 state_switch (ctx, STATE_REPOSITORY);
3257 case STATE_NAMESPACE:
3258 if (require_end_element (context, ctx, "namespace", element_name, error))
3260 ctx->current_module = NULL;
3261 state_switch (ctx, STATE_REPOSITORY);
3266 if (require_end_element (context, ctx, "alias", element_name, error))
3268 g_free (ctx->current_alias);
3269 ctx->current_alias = NULL;
3270 state_switch (ctx, STATE_NAMESPACE);
3274 case STATE_FUNCTION_RETURN:
3275 if (strcmp ("type", element_name) == 0)
3277 if (require_end_element (context, ctx, "return-value", element_name, error))
3279 state_switch (ctx, STATE_FUNCTION);
3283 case STATE_FUNCTION_PARAMETERS:
3284 if (require_end_element (context, ctx, "parameters", element_name, error))
3286 state_switch (ctx, STATE_FUNCTION);
3290 case STATE_FUNCTION_PARAMETER:
3291 if (strcmp ("type", element_name) == 0)
3293 if (require_end_element (context, ctx, "parameter", element_name, error))
3295 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
3299 case STATE_FUNCTION:
3302 if (ctx->node_stack == NULL)
3304 state_switch (ctx, STATE_NAMESPACE);
3308 g_debug("case STATE_FUNCTION %d", CURRENT_NODE (ctx)->type);
3309 if (ctx->in_embedded_state != STATE_NONE)
3311 state_switch (ctx, ctx->in_embedded_state);
3312 ctx->in_embedded_state = STATE_NONE;
3314 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
3315 state_switch (ctx, STATE_INTERFACE);
3316 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
3317 state_switch (ctx, STATE_CLASS);
3318 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_BOXED)
3319 state_switch (ctx, STATE_BOXED);
3320 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
3321 state_switch (ctx, STATE_STRUCT);
3322 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
3323 state_switch (ctx, STATE_UNION);
3324 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_ENUM ||
3325 CURRENT_NODE (ctx)->type == G_IR_NODE_FLAGS)
3326 state_switch (ctx, STATE_ENUM);
3329 int line_number, char_number;
3330 g_markup_parse_context_get_position (context, &line_number, &char_number);
3333 G_MARKUP_ERROR_INVALID_CONTENT,
3334 "Unexpected end tag '%s' on line %d char %d",
3336 line_number, char_number);
3342 case STATE_CLASS_FIELD:
3343 if (strcmp ("type", element_name) == 0)
3345 if (require_end_element (context, ctx, "field", element_name, error))
3347 state_switch (ctx, STATE_CLASS);
3351 case STATE_CLASS_PROPERTY:
3352 if (strcmp ("type", element_name) == 0)
3354 if (require_end_element (context, ctx, "property", element_name, error))
3356 state_switch (ctx, STATE_CLASS);
3361 if (require_end_element (context, ctx, "class", element_name, error))
3364 state_switch (ctx, STATE_NAMESPACE);
3368 case STATE_INTERFACE_PROPERTY:
3369 if (strcmp ("type", element_name) == 0)
3371 if (require_end_element (context, ctx, "property", element_name, error))
3373 state_switch (ctx, STATE_INTERFACE);
3377 case STATE_INTERFACE_FIELD:
3378 if (strcmp ("type", element_name) == 0)
3380 if (require_end_element (context, ctx, "field", element_name, error))
3382 state_switch (ctx, STATE_INTERFACE);
3386 case STATE_INTERFACE:
3387 if (require_end_element (context, ctx, "interface", element_name, error))
3390 state_switch (ctx, STATE_NAMESPACE);
3395 if (strcmp ("member", element_name) == 0)
3397 else if (strcmp ("function", element_name) == 0)
3399 else if (require_one_of_end_elements (context, ctx,
3400 element_name, error, "enumeration",
3404 state_switch (ctx, STATE_NAMESPACE);
3409 if (require_end_element (context, ctx, "glib:boxed", element_name, error))
3412 state_switch (ctx, STATE_NAMESPACE);
3416 case STATE_BOXED_FIELD:
3417 if (strcmp ("type", element_name) == 0)
3419 if (require_end_element (context, ctx, "field", element_name, error))
3421 state_switch (ctx, STATE_BOXED);
3425 case STATE_STRUCT_FIELD:
3426 if (strcmp ("type", element_name) == 0)
3428 if (require_end_element (context, ctx, "field", element_name, error))
3430 state_switch (ctx, STATE_STRUCT);
3435 if (require_end_element (context, ctx, "record", element_name, error))
3437 state_switch_end_struct_or_union (context, ctx, element_name, error);
3441 case STATE_UNION_FIELD:
3442 if (strcmp ("type", element_name) == 0)
3444 if (require_end_element (context, ctx, "field", element_name, error))
3446 state_switch (ctx, STATE_UNION);
3451 if (require_end_element (context, ctx, "union", element_name, error))
3453 state_switch_end_struct_or_union (context, ctx, element_name, error);
3456 case STATE_IMPLEMENTS:
3457 if (strcmp ("interface", element_name) == 0)
3459 if (require_end_element (context, ctx, "implements", element_name, error))
3460 state_switch (ctx, STATE_CLASS);
3462 case STATE_PREREQUISITE:
3463 if (require_end_element (context, ctx, "prerequisite", element_name, error))
3464 state_switch (ctx, STATE_INTERFACE);
3466 case STATE_NAMESPACE_CONSTANT:
3467 case STATE_CLASS_CONSTANT:
3468 case STATE_INTERFACE_CONSTANT:
3469 if (strcmp ("type", element_name) == 0)
3471 if (require_end_element (context, ctx, "constant", element_name, error))
3475 case STATE_NAMESPACE_CONSTANT:
3477 state_switch (ctx, STATE_NAMESPACE);
3479 case STATE_CLASS_CONSTANT:
3480 state_switch (ctx, STATE_CLASS);
3482 case STATE_INTERFACE_CONSTANT:
3483 state_switch (ctx, STATE_INTERFACE);
3486 g_assert_not_reached ();
3492 if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
3493 (strcmp ("varargs", element_name) == 0))
3498 case STATE_ATTRIBUTE:
3499 if (strcmp ("attribute", element_name) == 0)
3501 state_switch (ctx, ctx->prev_state);
3505 case STATE_PASSTHROUGH:
3506 ctx->unknown_depth -= 1;
3507 g_assert (ctx->unknown_depth >= 0);
3508 if (ctx->unknown_depth == 0)
3509 state_switch (ctx, ctx->prev_state);
3512 g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
3517 text_handler (GMarkupParseContext *context,
3523 /* FIXME warn about non-whitespace text */
3527 cleanup (GMarkupParseContext *context,
3531 ParseContext *ctx = user_data;
3534 for (m = ctx->modules; m; m = m->next)
3535 _g_ir_module_free (m->data);
3536 g_list_free (ctx->modules);
3537 ctx->modules = NULL;
3539 ctx->current_module = NULL;
3543 * _g_ir_parser_parse_string:
3544 * @parser: a #GIrParser
3545 * @namespace: the namespace of the string
3546 * @filename: (allow-none): Path to parsed file, or %NULL
3547 * @buffer: the data containing the XML
3548 * @length: length of the data
3549 * @error: return location for a #GError, or %NULL
3551 * Parse a string that holds a complete GIR XML file, and return a list of a
3552 * a #GirModule for each <namespace/> element within the file.
3554 * Returns: (transfer none): a new #GirModule
3557 _g_ir_parser_parse_string (GIrParser *parser,
3558 const gchar *namespace,
3559 const gchar *filename,
3560 const gchar *buffer,
3564 ParseContext ctx = { 0 };
3565 GMarkupParseContext *context;
3567 ctx.parser = parser;
3568 ctx.state = STATE_START;
3569 ctx.file_path = filename;
3570 ctx.namespace = namespace;
3571 ctx.include_modules = NULL;
3572 ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
3573 ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
3575 ctx.dependencies = NULL;
3576 ctx.current_module = NULL;
3578 context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
3580 if (!g_markup_parse_context_parse (context, buffer, length, error))
3583 if (!g_markup_parse_context_end_parse (context, error))
3586 g_markup_parse_context_free (context);
3588 ctx.state = STATE_START;
3589 context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL);
3590 if (!g_markup_parse_context_parse (context, buffer, length, error))
3593 if (!g_markup_parse_context_end_parse (context, error))
3596 parser->parsed_modules = g_list_concat (g_list_copy (ctx.modules),
3597 parser->parsed_modules);
3601 if (ctx.modules == NULL)
3603 /* An error occurred before we created a module, so we haven't
3604 * transferred ownership of these hash tables to the module.
3606 if (ctx.aliases != NULL)
3607 g_hash_table_destroy (ctx.aliases);
3608 if (ctx.disguised_structures != NULL)
3609 g_hash_table_destroy (ctx.disguised_structures);
3610 g_list_free (ctx.include_modules);
3613 g_markup_parse_context_free (context);
3616 return ctx.modules->data;
3618 if (error && *error == NULL)
3621 G_MARKUP_ERROR_INVALID_CONTENT,
3622 "Expected namespace element in the gir file");
3627 * _g_ir_parser_parse_file:
3628 * @parser: a #GIrParser
3629 * @filename: filename to parse
3630 * @error: return location for a #GError, or %NULL
3632 * Parse GIR XML file, and return a list of a a #GirModule for each
3633 * <namespace/> element within the file.
3635 * Returns: (transfer container): a newly allocated list of #GIrModule. The modules themselves
3636 * are owned by the #GIrParser and will be freed along with the parser.
3639 _g_ir_parser_parse_file (GIrParser *parser,
3640 const gchar *filename,
3650 if (!g_str_has_suffix (filename, ".gir"))
3654 G_MARKUP_ERROR_INVALID_CONTENT,
3655 "Expected filename to end with '.gir'");
3659 g_debug ("[parsing] filename %s", filename);
3661 slash = g_strrstr (filename, "/");
3663 namespace = g_strdup (filename);
3665 namespace = g_strdup (slash+1);
3666 namespace[strlen(namespace)-4] = '\0';
3668 /* Remove version */
3669 dash = strstr (namespace, "-");
3673 if (!g_file_get_contents (filename, &buffer, &length, error))
3676 module = _g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error);