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"
35 GList *parsed_modules; /* All previously parsed modules */
45 STATE_NAMESPACE, /* 5 */
49 STATE_FUNCTION_RETURN,
50 STATE_FUNCTION_PARAMETERS, /* 10 */
51 STATE_FUNCTION_PARAMETER,
55 STATE_INTERFACE, /* 15 */
56 STATE_INTERFACE_PROPERTY,
57 STATE_INTERFACE_FIELD,
67 STATE_NAMESPACE_CONSTANT,
69 STATE_INTERFACE_CONSTANT,
76 typedef struct _ParseContext ParseContext;
83 ParseState prev_state;
86 GList *include_modules;
89 GHashTable *disguised_structures;
91 const char *namespace;
93 GIrModule *current_module;
95 GIrNode *current_typed;
98 GList *type_parameters;
101 #define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
103 static void start_element_handler (GMarkupParseContext *context,
104 const gchar *element_name,
105 const gchar **attribute_names,
106 const gchar **attribute_values,
109 static void end_element_handler (GMarkupParseContext *context,
110 const gchar *element_name,
113 static void text_handler (GMarkupParseContext *context,
118 static void cleanup (GMarkupParseContext *context,
122 static GMarkupParser markup_parser =
124 start_element_handler,
132 start_alias (GMarkupParseContext *context,
133 const gchar *element_name,
134 const gchar **attribute_names,
135 const gchar **attribute_values,
139 static const gchar *find_attribute (const gchar *name,
140 const gchar **attribute_names,
141 const gchar **attribute_values);
145 g_ir_parser_new (void)
147 GIrParser *parser = g_slice_new0 (GIrParser);
153 g_ir_parser_free (GIrParser *parser)
157 if (parser->includes)
158 g_strfreev (parser->includes);
160 for (l = parser->parsed_modules; l; l = l->next)
161 g_ir_module_free (l->data);
163 g_slice_free (GIrParser, parser);
167 g_ir_parser_set_includes (GIrParser *parser,
168 const gchar *const *includes)
170 if (parser->includes)
171 g_strfreev (parser->includes);
173 parser->includes = g_strdupv ((char **)includes);
177 firstpass_start_element_handler (GMarkupParseContext *context,
178 const gchar *element_name,
179 const gchar **attribute_names,
180 const gchar **attribute_values,
184 ParseContext *ctx = user_data;
186 if (strcmp (element_name, "alias") == 0)
188 start_alias (context, element_name, attribute_names, attribute_values,
191 else if (strcmp (element_name, "record") == 0)
194 const gchar *disguised;
196 name = find_attribute ("name", attribute_names, attribute_values);
197 disguised = find_attribute ("disguised", attribute_names, attribute_values);
199 if (disguised && strcmp (disguised, "1") == 0)
203 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
204 g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
210 firstpass_end_element_handler (GMarkupParseContext *context,
211 const gchar *element_name,
217 static GMarkupParser firstpass_parser =
219 firstpass_start_element_handler,
220 firstpass_end_element_handler,
227 locate_gir (GIrParser *parser,
230 const gchar *const *datadirs;
231 const gchar *const *dir;
234 datadirs = g_get_system_data_dirs ();
236 if (parser->includes != NULL)
238 for (dir = (const gchar *const *)parser->includes; *dir; dir++)
240 path = g_build_filename (*dir, girname, NULL);
241 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
247 for (dir = datadirs; *dir; dir++)
249 path = g_build_filename (*dir, GIR_SUFFIX, girname, NULL);
250 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
256 path = g_build_filename (GIR_DIR, girname, NULL);
257 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
263 #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \
265 int line_number, char_number; \
266 g_markup_parse_context_get_position (context, &line_number, &char_number); \
267 g_set_error (error, \
269 G_MARKUP_ERROR_INVALID_CONTENT, \
270 "Line %d, character %d: The attribute '%s' on the element '%s' must be specified", \
271 line_number, char_number, attribute, element); \
275 backtrace_stderr (void)
277 #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
283 size = backtrace (array, 50);
284 strings = (char**) backtrace_symbols (array, size);
286 fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size);
288 for (i = 0; i < size; i++)
289 fprintf (stderr, "%s\n", strings[i]);
291 fprintf (stderr, "--- END BACKTRACE ---\n", size);
299 find_attribute (const gchar *name,
300 const gchar **attribute_names,
301 const gchar **attribute_values)
305 for (i = 0; attribute_names[i] != NULL; i++)
306 if (strcmp (attribute_names[i], name) == 0)
307 return attribute_values[i];
313 state_switch (ParseContext *ctx, ParseState newstate)
315 g_debug ("State: %d", newstate);
316 ctx->prev_state = ctx->state;
317 ctx->state = newstate;
321 pop_node (ParseContext *ctx)
323 g_assert (ctx->node_stack != 0);
325 GSList *top = ctx->node_stack;
326 GIrNode *node = top->data;
328 g_debug ("popping node %d %s", node->type, node->name);
329 ctx->node_stack = top->next;
330 g_slist_free_1 (top);
335 push_node (ParseContext *ctx, GIrNode *node)
337 g_debug ("pushing node %d %s", node->type, node->name);
338 ctx->node_stack = g_slist_prepend (ctx->node_stack, node);
341 static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
342 gboolean in_gobject);
350 static BasicTypeInfo basic_types[] = {
351 { "none", GI_TYPE_TAG_VOID, 0 },
352 { "any", GI_TYPE_TAG_VOID, 1 },
354 { "bool", GI_TYPE_TAG_BOOLEAN, 0 },
355 { "char", GI_TYPE_TAG_INT8, 0 },
356 { "int8", GI_TYPE_TAG_INT8, 0 },
357 { "uint8", GI_TYPE_TAG_UINT8, 0 },
358 { "int16", GI_TYPE_TAG_INT16, 0 },
359 { "uint16", GI_TYPE_TAG_UINT16, 0 },
360 { "int32", GI_TYPE_TAG_INT32, 0 },
361 { "uint32", GI_TYPE_TAG_UINT32, 0 },
362 { "int64", GI_TYPE_TAG_INT64, 0 },
363 { "uint64", GI_TYPE_TAG_UINT64, 0 },
364 { "int", GI_TYPE_TAG_INT, 0 },
365 { "uint", GI_TYPE_TAG_UINT, 0 },
366 { "long", GI_TYPE_TAG_LONG, 0 },
367 { "ulong", GI_TYPE_TAG_ULONG, 0 },
368 { "ssize_t", GI_TYPE_TAG_SSIZE, 0 },
369 { "ssize", GI_TYPE_TAG_SSIZE, 0 },
370 { "size_t", GI_TYPE_TAG_SIZE, 0 },
371 { "size", GI_TYPE_TAG_SIZE, 0 },
372 { "float", GI_TYPE_TAG_FLOAT, 0 },
373 { "double", GI_TYPE_TAG_DOUBLE, 0 },
374 { "time_t", GI_TYPE_TAG_TIME_T, 0 },
375 { "GType", GI_TYPE_TAG_GTYPE, 0 },
376 { "utf8", GI_TYPE_TAG_UTF8, 1 },
377 { "filename", GI_TYPE_TAG_FILENAME,1 },
380 static const BasicTypeInfo *
381 parse_basic (const char *str)
384 gint n_basic = G_N_ELEMENTS (basic_types);
386 for (i = 0; i < n_basic; i++)
388 if (g_str_has_prefix (str, basic_types[i].str))
389 return &(basic_types[i]);
395 parse_type_internal (const gchar *str, char **next, gboolean in_glib,
398 const BasicTypeInfo *basic;
400 char *temporary_type = NULL;
402 type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
404 type->unparsed = g_strdup (str);
406 /* See comment below on GLib.List handling */
407 if (in_gobject && strcmp (str, "Type") == 0)
409 temporary_type = g_strdup ("GLib.Type");
410 str = temporary_type;
413 basic = parse_basic (str);
416 type->is_basic = TRUE;
417 type->tag = basic->tag;
418 type->is_pointer = basic->pointer;
420 str += strlen(basic->str);
424 /* If we're inside GLib, handle "List" etc. by prefixing with
425 * "GLib." so the parsing code below doesn't have to get more
428 if (g_str_has_prefix (str, "List<") ||
429 strcmp (str, "List") == 0)
431 temporary_type = g_strdup_printf ("GLib.List%s", str + 4);
432 str = temporary_type;
434 else if (g_str_has_prefix (str, "SList<") ||
435 strcmp (str, "SList") == 0)
437 temporary_type = g_strdup_printf ("GLib.SList%s", str + 5);
438 str = temporary_type;
440 else if (g_str_has_prefix (str, "HashTable<") ||
441 strcmp (str, "HashTable") == 0)
443 temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9);
444 str = temporary_type;
446 else if (g_str_has_prefix (str, "Error<") ||
447 strcmp (str, "Error") == 0)
449 temporary_type = g_strdup_printf ("GLib.Error%s", str + 5);
450 str = temporary_type;
455 /* found a basic type */;
456 else if (g_str_has_prefix (str, "GLib.List") ||
457 g_str_has_prefix (str, "GLib.SList"))
459 str += strlen ("GLib.");
460 if (g_str_has_prefix (str, "List"))
462 type->tag = GI_TYPE_TAG_GLIST;
463 type->is_glist = TRUE;
464 type->is_pointer = TRUE;
465 str += strlen ("List");
469 type->tag = GI_TYPE_TAG_GSLIST;
470 type->is_gslist = TRUE;
471 type->is_pointer = TRUE;
472 str += strlen ("SList");
475 else if (g_str_has_prefix (str, "GLib.HashTable"))
477 str += strlen ("GLib.");
479 type->tag = GI_TYPE_TAG_GHASH;
480 type->is_ghashtable = TRUE;
481 type->is_pointer = TRUE;
482 str += strlen ("HashTable");
484 else if (g_str_has_prefix (str, "GLib.Error"))
486 str += strlen ("GLib.");
488 type->tag = GI_TYPE_TAG_ERROR;
489 type->is_error = TRUE;
490 type->is_pointer = TRUE;
491 str += strlen ("Error");
498 end = strchr (str, '>');
499 tmp = g_strndup (str, end - str);
500 type->errors = g_strsplit (tmp, ",", 0);
508 type->tag = GI_TYPE_TAG_INTERFACE;
509 type->is_interface = TRUE;
510 const char *start = str;
512 /* must be an interface type */
513 while (g_ascii_isalnum (*str) ||
520 type->interface = g_strndup (start, str - start);
525 g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR);
526 g_free (temporary_type);
530 g_ir_node_free ((GIrNode *)type);
531 g_free (temporary_type);
536 resolve_aliases (ParseContext *ctx, const gchar *type)
540 GSList *seen_values = NULL;
544 if (strchr (type, '.') == NULL)
546 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
555 seen_values = g_slist_prepend (seen_values, (char*)lookup);
556 while (g_hash_table_lookup_extended (ctx->current_module->aliases, lookup, &orig, &value))
558 g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
560 if (g_slist_find_custom (seen_values, lookup,
561 (GCompareFunc)strcmp) != NULL)
563 seen_values = g_slist_prepend (seen_values, (gchar*)lookup);
565 g_slist_free (seen_values);
567 if (lookup == prefixed)
576 is_disguised_structure (ParseContext *ctx, const gchar *type)
582 if (strchr (type, '.') == NULL)
584 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
593 result = g_hash_table_lookup (ctx->current_module->disguised_structures,
602 parse_type (ParseContext *ctx, const gchar *type)
605 const BasicTypeInfo *basic;
606 gboolean in_glib, in_gobject;
608 in_glib = strcmp (ctx->namespace, "GLib") == 0;
609 in_gobject = strcmp (ctx->namespace, "GObject") == 0;
611 /* Do not search aliases for basic types */
612 basic = parse_basic (type);
614 type = resolve_aliases (ctx, type);
616 node = parse_type_internal (type, NULL, in_glib, in_gobject);
618 g_debug ("Parsed type: %s => %d", type, node->tag);
620 g_critical ("Failed to parse type: '%s'", type);
626 start_glib_boxed (GMarkupParseContext *context,
627 const gchar *element_name,
628 const gchar **attribute_names,
629 const gchar **attribute_values,
634 const gchar *typename;
635 const gchar *typeinit;
636 const gchar *deprecated;
639 if (!(strcmp (element_name, "glib:boxed") == 0 &&
640 ctx->state == STATE_NAMESPACE))
643 name = find_attribute ("glib:name", attribute_names, attribute_values);
644 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
645 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
646 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
650 MISSING_ATTRIBUTE (context, error, element_name, "glib:name");
653 else if (typename == NULL)
655 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
658 else if (typeinit == NULL)
660 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
664 boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED);
666 ((GIrNode *)boxed)->name = g_strdup (name);
667 boxed->gtype_name = g_strdup (typename);
668 boxed->gtype_init = g_strdup (typeinit);
670 boxed->deprecated = TRUE;
672 boxed->deprecated = FALSE;
674 push_node (ctx, (GIrNode *)boxed);
675 ctx->current_module->entries =
676 g_list_append (ctx->current_module->entries, boxed);
678 state_switch (ctx, STATE_BOXED);
684 start_function (GMarkupParseContext *context,
685 const gchar *element_name,
686 const gchar **attribute_names,
687 const gchar **attribute_values,
693 const gchar *deprecated;
695 GIrNodeFunction *function;
696 gboolean found = FALSE;
700 case STATE_NAMESPACE:
701 found = (strcmp (element_name, "function") == 0 ||
702 strcmp (element_name, "callback") == 0);
705 found = strcmp (element_name, "function") == 0;
710 found = (found || strcmp (element_name, "constructor") == 0);
712 case STATE_INTERFACE:
714 strcmp (element_name, "method") == 0 ||
715 strcmp (element_name, "callback") == 0);
724 name = find_attribute ("name", attribute_names, attribute_values);
725 symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
726 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
727 throws = find_attribute ("throws", attribute_names, attribute_values);
731 MISSING_ATTRIBUTE (context, error, element_name, "name");
734 else if (strcmp (element_name, "callback") != 0 && symbol == NULL)
736 MISSING_ATTRIBUTE (context, error, element_name, "c:identifier");
740 function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION);
742 ((GIrNode *)function)->name = g_strdup (name);
743 function->symbol = g_strdup (symbol);
744 function->parameters = NULL;
746 function->deprecated = TRUE;
748 function->deprecated = FALSE;
750 if (strcmp (element_name, "method") == 0 ||
751 strcmp (element_name, "constructor") == 0)
753 function->is_method = TRUE;
755 if (strcmp (element_name, "constructor") == 0)
756 function->is_constructor = TRUE;
758 function->is_constructor = FALSE;
762 function->is_method = FALSE;
763 function->is_setter = FALSE;
764 function->is_getter = FALSE;
765 function->is_constructor = FALSE;
766 if (strcmp (element_name, "callback") == 0)
767 ((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
770 if (throws && strcmp (throws, "1") == 0)
771 function->throws = TRUE;
773 function->throws = FALSE;
775 if (ctx->node_stack == NULL)
777 ctx->current_module->entries =
778 g_list_append (ctx->current_module->entries, function);
781 switch (CURRENT_NODE (ctx)->type)
783 case G_IR_NODE_INTERFACE:
784 case G_IR_NODE_OBJECT:
786 GIrNodeInterface *iface;
788 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
789 iface->members = g_list_append (iface->members, function);
792 case G_IR_NODE_BOXED:
796 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
797 boxed->members = g_list_append (boxed->members, function);
800 case G_IR_NODE_STRUCT:
802 GIrNodeStruct *struct_;
804 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
805 struct_->members = g_list_append (struct_->members, function); }
807 case G_IR_NODE_UNION:
809 GIrNodeUnion *union_;
811 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
812 union_->members = g_list_append (union_->members, function);
816 g_assert_not_reached ();
819 push_node(ctx, (GIrNode *)function);
820 state_switch (ctx, STATE_FUNCTION);
826 parse_param_transfer (GIrNodeParam *param, const gchar *transfer)
828 if (transfer == NULL)
830 g_warning ("required attribute 'transfer-ownership' missing");
832 else if (strcmp (transfer, "none") == 0)
834 param->transfer = FALSE;
835 param->shallow_transfer = FALSE;
837 else if (strcmp (transfer, "container") == 0)
839 param->transfer = FALSE;
840 param->shallow_transfer = TRUE;
842 else if (strcmp (transfer, "full") == 0)
844 param->transfer = TRUE;
845 param->shallow_transfer = FALSE;
849 g_warning ("Unknown transfer-ownership value: %s", transfer);
854 start_parameter (GMarkupParseContext *context,
855 const gchar *element_name,
856 const gchar **attribute_names,
857 const gchar **attribute_values,
862 const gchar *direction;
865 const gchar *optional;
866 const gchar *allow_none;
867 const gchar *transfer;
869 const gchar *closure;
870 const gchar *destroy;
873 if (!(strcmp (element_name, "parameter") == 0 &&
874 ctx->state == STATE_FUNCTION_PARAMETERS))
877 name = find_attribute ("name", attribute_names, attribute_values);
878 direction = find_attribute ("direction", attribute_names, attribute_values);
879 retval = find_attribute ("retval", attribute_names, attribute_values);
880 dipper = find_attribute ("dipper", attribute_names, attribute_values);
881 optional = find_attribute ("optional", attribute_names, attribute_values);
882 allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
883 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
884 scope = find_attribute ("scope", attribute_names, attribute_values);
885 closure = find_attribute ("closure", attribute_names, attribute_values);
886 destroy = find_attribute ("destroy", attribute_names, attribute_values);
891 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
893 ctx->current_typed = (GIrNode*) param;
894 ctx->current_typed->name = g_strdup (name);
896 state_switch (ctx, STATE_FUNCTION_PARAMETER);
898 if (direction && strcmp (direction, "out") == 0)
903 else if (direction && strcmp (direction, "inout") == 0)
914 if (retval && strcmp (retval, "1") == 0)
915 param->retval = TRUE;
917 param->retval = FALSE;
919 if (dipper && strcmp (dipper, "1") == 0)
920 param->dipper = TRUE;
922 param->dipper = FALSE;
924 if (optional && strcmp (optional, "1") == 0)
925 param->optional = TRUE;
927 param->optional = FALSE;
929 if (allow_none && strcmp (allow_none, "1") == 0)
930 param->allow_none = TRUE;
932 param->allow_none = FALSE;
934 parse_param_transfer (param, transfer);
936 if (scope && strcmp (scope, "call") == 0)
937 param->scope = GI_SCOPE_TYPE_CALL;
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,
2325 gchar *girpath, *girname;
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 girname = g_strdup_printf ("%s-%s.gir", name, version);
2355 girpath = locate_gir (ctx->parser, girname);
2357 if (girpath == NULL)
2361 G_MARKUP_ERROR_INVALID_CONTENT,
2362 "Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir",
2369 g_debug ("Parsing include %s", girpath);
2371 if (!g_file_get_contents (girpath, &buffer, &length, error))
2378 modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error);
2379 success = error != NULL;
2381 ctx->include_modules = g_list_concat (ctx->include_modules,
2389 extern GLogLevelFlags logged_levels;
2392 start_element_handler (GMarkupParseContext *context,
2393 const gchar *element_name,
2394 const gchar **attribute_names,
2395 const gchar **attribute_values,
2399 ParseContext *ctx = user_data;
2400 gint line_number, char_number;
2402 if (logged_levels & G_LOG_LEVEL_DEBUG)
2404 GString *tags = g_string_new ("");
2406 for (i = 0; attribute_names[i]; i++)
2407 g_string_append_printf (tags, "%s=\"%s\" ",
2409 attribute_values[i]);
2413 g_string_insert_c (tags, 0, ' ');
2414 g_string_truncate (tags, tags->len - 1);
2416 g_debug ("<%s%s>", element_name, tags->str);
2417 g_string_free (tags, TRUE);
2420 switch (element_name[0])
2423 if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0)
2425 state_switch (ctx, STATE_ALIAS);
2428 if (start_type (context, element_name,
2429 attribute_names, attribute_values,
2432 else if (start_attribute (context, element_name,
2433 attribute_names, attribute_values,
2438 if (start_enum (context, element_name,
2439 attribute_names, attribute_values,
2444 if (start_function (context, element_name,
2445 attribute_names, attribute_values,
2448 else if (start_constant (context, element_name,
2449 attribute_names, attribute_values,
2452 else if (start_class (context, element_name,
2453 attribute_names, attribute_values,
2459 if (start_discriminator (context, element_name,
2460 attribute_names, attribute_values,
2466 if (start_enum (context, element_name,
2467 attribute_names, attribute_values,
2470 else if (start_errordomain (context, element_name,
2471 attribute_names, attribute_values,
2477 if (start_function (context, element_name,
2478 attribute_names, attribute_values,
2481 else if (start_field (context, element_name,
2482 attribute_names, attribute_values,
2488 if (start_glib_boxed (context, element_name,
2489 attribute_names, attribute_values,
2492 else if (start_glib_signal (context, element_name,
2493 attribute_names, attribute_values,
2499 if (strcmp (element_name, "include") == 0 &&
2500 ctx->state == STATE_REPOSITORY)
2503 const gchar *version;
2505 name = find_attribute ("name", attribute_names, attribute_values);
2506 version = find_attribute ("version", attribute_names, attribute_values);
2510 MISSING_ATTRIBUTE (context, error, element_name, "name");
2513 if (version == NULL)
2515 MISSING_ATTRIBUTE (context, error, element_name, "version");
2519 if (!parse_include (context, ctx, name, version, error))
2522 ctx->dependencies = g_list_prepend (ctx->dependencies,
2523 g_strdup_printf ("%s-%s", name, version));
2526 state_switch (ctx, STATE_INCLUDE);
2529 if (start_interface (context, element_name,
2530 attribute_names, attribute_values,
2533 else if (start_implements (context, element_name,
2534 attribute_names, attribute_values,
2540 if (start_function (context, element_name,
2541 attribute_names, attribute_values,
2544 else if (start_member (context, element_name,
2545 attribute_names, attribute_values,
2551 if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2553 const gchar *name, *version, *shared_library, *cprefix;
2555 if (ctx->current_module != NULL)
2559 G_MARKUP_ERROR_INVALID_CONTENT,
2560 "Only one <namespace/> element is currently allowed per <repository/>");
2564 name = find_attribute ("name", attribute_names, attribute_values);
2565 version = find_attribute ("version", attribute_names, attribute_values);
2566 shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2567 cprefix = find_attribute ("c:prefix", attribute_names, attribute_values);
2570 MISSING_ATTRIBUTE (context, error, element_name, "name");
2571 else if (version == NULL)
2572 MISSING_ATTRIBUTE (context, error, element_name, "version");
2577 if (strcmp (name, ctx->namespace) != 0)
2580 G_MARKUP_ERROR_INVALID_CONTENT,
2581 "<namespace/> name element '%s' doesn't match file name '%s'",
2582 name, ctx->namespace);
2584 ctx->current_module = g_ir_module_new (name, version, shared_library, cprefix);
2586 ctx->current_module->aliases = ctx->aliases;
2587 ctx->aliases = NULL;
2588 ctx->current_module->disguised_structures = ctx->disguised_structures;
2589 ctx->disguised_structures = NULL;
2591 for (l = ctx->include_modules; l; l = l->next)
2592 g_ir_module_add_include_module (ctx->current_module, l->data);
2594 g_list_free (ctx->include_modules);
2595 ctx->include_modules = NULL;
2597 ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2598 ctx->current_module->dependencies = ctx->dependencies;
2600 state_switch (ctx, STATE_NAMESPACE);
2607 if (start_property (context, element_name,
2608 attribute_names, attribute_values,
2611 else if (strcmp (element_name, "parameters") == 0 &&
2612 ctx->state == STATE_FUNCTION)
2614 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2618 else if (start_parameter (context, element_name,
2619 attribute_names, attribute_values,
2622 else if (strcmp (element_name, "prerequisite") == 0 &&
2623 ctx->state == STATE_INTERFACE)
2627 name = find_attribute ("name", attribute_names, attribute_values);
2629 state_switch (ctx, STATE_PREREQUISITE);
2632 MISSING_ATTRIBUTE (context, error, element_name, "name");
2635 GIrNodeInterface *iface;
2637 iface = (GIrNodeInterface *)CURRENT_NODE(ctx);
2638 iface->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
2642 else if (strcmp (element_name, "package") == 0 &&
2643 ctx->state == STATE_REPOSITORY)
2645 state_switch (ctx, STATE_PACKAGE);
2651 if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
2653 const gchar *version;
2655 version = find_attribute ("version", attribute_names, attribute_values);
2657 if (version == NULL)
2658 MISSING_ATTRIBUTE (context, error, element_name, "version");
2659 else if (strcmp (version, "1.0") != 0)
2662 G_MARKUP_ERROR_INVALID_CONTENT,
2663 "Unsupported version '%s'",
2666 state_switch (ctx, STATE_REPOSITORY);
2670 else if (start_return_value (context, element_name,
2671 attribute_names, attribute_values,
2674 else if (start_struct (context, element_name,
2675 attribute_names, attribute_values,
2681 if (start_union (context, element_name,
2682 attribute_names, attribute_values,
2688 if (start_type (context, element_name,
2689 attribute_names, attribute_values,
2695 if (start_vfunc (context, element_name,
2696 attribute_names, attribute_values,
2699 if (start_type (context, element_name,
2700 attribute_names, attribute_values,
2706 if (ctx->state != STATE_UNKNOWN)
2708 state_switch (ctx, STATE_UNKNOWN);
2709 ctx->unknown_depth = 1;
2713 ctx->unknown_depth += 1;
2719 g_markup_parse_context_get_position (context, &line_number, &char_number);
2721 fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message);
2722 backtrace_stderr ();
2727 require_one_of_end_elements (GMarkupParseContext *context,
2729 const char *actual_name,
2734 int line_number, char_number;
2735 const char *expected;
2736 gboolean matched = FALSE;
2738 va_start (args, error);
2740 while ((expected = va_arg (args, const char*)) != NULL)
2742 if (strcmp (expected, actual_name) == 0)
2754 g_markup_parse_context_get_position (context, &line_number, &char_number);
2757 G_MARKUP_ERROR_INVALID_CONTENT,
2758 "Unexpected end tag '%s' on line %d char %d; current state=%d",
2760 line_number, char_number, ctx->state);
2766 state_switch_end_struct_or_union (GMarkupParseContext *context,
2768 const gchar *element_name,
2772 if (ctx->node_stack == NULL)
2774 state_switch (ctx, STATE_NAMESPACE);
2778 if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2779 state_switch (ctx, STATE_STRUCT);
2780 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2781 state_switch (ctx, STATE_UNION);
2782 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2783 state_switch (ctx, STATE_CLASS);
2786 int line_number, char_number;
2787 g_markup_parse_context_get_position (context, &line_number, &char_number);
2790 G_MARKUP_ERROR_INVALID_CONTENT,
2791 "Unexpected end tag '%s' on line %d char %d",
2793 line_number, char_number);
2801 require_end_element (GMarkupParseContext *context,
2803 const char *expected_name,
2804 const char *actual_name,
2807 return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
2811 end_element_handler (GMarkupParseContext *context,
2812 const gchar *element_name,
2816 ParseContext *ctx = user_data;
2818 g_debug ("</%s>", element_name);
2824 /* no need to GError here, GMarkup already catches this */
2827 case STATE_REPOSITORY:
2828 state_switch (ctx, STATE_END);
2832 if (require_end_element (context, ctx, "include", element_name, error))
2834 state_switch (ctx, STATE_REPOSITORY);
2839 if (require_end_element (context, ctx, "package", element_name, error))
2841 state_switch (ctx, STATE_REPOSITORY);
2845 case STATE_NAMESPACE:
2846 if (require_end_element (context, ctx, "namespace", element_name, error))
2848 ctx->current_module = NULL;
2849 state_switch (ctx, STATE_REPOSITORY);
2854 if (require_end_element (context, ctx, "alias", element_name, error))
2856 state_switch (ctx, STATE_NAMESPACE);
2860 case STATE_FUNCTION_RETURN:
2861 if (strcmp ("type", element_name) == 0)
2863 if (require_end_element (context, ctx, "return-value", element_name, error))
2865 state_switch (ctx, STATE_FUNCTION);
2869 case STATE_FUNCTION_PARAMETERS:
2870 if (require_end_element (context, ctx, "parameters", element_name, error))
2872 state_switch (ctx, STATE_FUNCTION);
2876 case STATE_FUNCTION_PARAMETER:
2877 if (strcmp ("type", element_name) == 0)
2879 if (require_end_element (context, ctx, "parameter", element_name, error))
2881 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2885 case STATE_FUNCTION:
2888 if (ctx->node_stack == NULL)
2890 state_switch (ctx, STATE_NAMESPACE);
2894 if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
2895 state_switch (ctx, STATE_INTERFACE);
2896 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2897 state_switch (ctx, STATE_CLASS);
2898 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_BOXED)
2899 state_switch (ctx, STATE_BOXED);
2900 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2901 state_switch (ctx, STATE_STRUCT);
2902 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2903 state_switch (ctx, STATE_UNION);
2906 int line_number, char_number;
2907 g_markup_parse_context_get_position (context, &line_number, &char_number);
2910 G_MARKUP_ERROR_INVALID_CONTENT,
2911 "Unexpected end tag '%s' on line %d char %d",
2913 line_number, char_number);
2919 case STATE_CLASS_FIELD:
2920 if (strcmp ("type", element_name) == 0)
2922 if (require_end_element (context, ctx, "field", element_name, error))
2924 state_switch (ctx, STATE_CLASS);
2928 case STATE_CLASS_PROPERTY:
2929 if (strcmp ("type", element_name) == 0)
2931 if (require_end_element (context, ctx, "property", element_name, error))
2933 state_switch (ctx, STATE_CLASS);
2938 if (require_end_element (context, ctx, "class", element_name, error))
2941 state_switch (ctx, STATE_NAMESPACE);
2945 case STATE_ERRORDOMAIN:
2946 if (require_end_element (context, ctx, "errordomain", element_name, error))
2949 state_switch (ctx, STATE_NAMESPACE);
2953 case STATE_INTERFACE_PROPERTY:
2954 if (strcmp ("type", element_name) == 0)
2956 if (require_end_element (context, ctx, "property", element_name, error))
2958 state_switch (ctx, STATE_INTERFACE);
2962 case STATE_INTERFACE_FIELD:
2963 if (strcmp ("type", element_name) == 0)
2965 if (require_end_element (context, ctx, "field", element_name, error))
2967 state_switch (ctx, STATE_INTERFACE);
2971 case STATE_INTERFACE:
2972 if (require_end_element (context, ctx, "interface", element_name, error))
2975 state_switch (ctx, STATE_NAMESPACE);
2980 if (strcmp ("member", element_name) == 0)
2982 else if (require_one_of_end_elements (context, ctx,
2983 element_name, error, "enumeration",
2987 state_switch (ctx, STATE_NAMESPACE);
2992 if (require_end_element (context, ctx, "glib:boxed", element_name, error))
2995 state_switch (ctx, STATE_NAMESPACE);
2999 case STATE_BOXED_FIELD:
3000 if (strcmp ("type", element_name) == 0)
3002 if (require_end_element (context, ctx, "field", element_name, error))
3004 state_switch (ctx, STATE_BOXED);
3008 case STATE_STRUCT_FIELD:
3009 if (strcmp ("type", element_name) == 0)
3011 if (require_end_element (context, ctx, "field", element_name, error))
3013 state_switch (ctx, STATE_STRUCT);
3018 if (require_end_element (context, ctx, "record", element_name, error))
3020 state_switch_end_struct_or_union (context, ctx, element_name, error);
3024 case STATE_UNION_FIELD:
3025 if (strcmp ("type", element_name) == 0)
3027 if (require_end_element (context, ctx, "field", element_name, error))
3029 state_switch (ctx, STATE_UNION);
3034 if (require_end_element (context, ctx, "union", element_name, error))
3036 state_switch_end_struct_or_union (context, ctx, element_name, error);
3039 case STATE_IMPLEMENTS:
3040 if (strcmp ("interface", element_name) == 0)
3042 if (require_end_element (context, ctx, "implements", element_name, error))
3043 state_switch (ctx, STATE_CLASS);
3045 case STATE_PREREQUISITE:
3046 if (require_end_element (context, ctx, "prerequisite", element_name, error))
3047 state_switch (ctx, STATE_INTERFACE);
3049 case STATE_NAMESPACE_CONSTANT:
3050 case STATE_CLASS_CONSTANT:
3051 case STATE_INTERFACE_CONSTANT:
3052 if (strcmp ("type", element_name) == 0)
3054 if (require_end_element (context, ctx, "constant", element_name, error))
3058 case STATE_NAMESPACE_CONSTANT:
3060 state_switch (ctx, STATE_NAMESPACE);
3062 case STATE_CLASS_CONSTANT:
3063 state_switch (ctx, STATE_CLASS);
3065 case STATE_INTERFACE_CONSTANT:
3066 state_switch (ctx, STATE_INTERFACE);
3069 g_assert_not_reached ();
3075 if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
3076 (strcmp ("varargs", element_name) == 0))
3081 case STATE_ATTRIBUTE:
3082 if (strcmp ("attribute", element_name) == 0)
3084 state_switch (ctx, ctx->prev_state);
3089 ctx->unknown_depth -= 1;
3090 if (ctx->unknown_depth == 0)
3091 state_switch (ctx, ctx->prev_state);
3094 g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
3099 text_handler (GMarkupParseContext *context,
3105 /* FIXME warn about non-whitespace text */
3109 cleanup (GMarkupParseContext *context,
3113 ParseContext *ctx = user_data;
3116 for (m = ctx->modules; m; m = m->next)
3117 g_ir_module_free (m->data);
3118 g_list_free (ctx->modules);
3119 ctx->modules = NULL;
3121 ctx->current_module = NULL;
3125 post_filter_toplevel_varargs_functions (GList *list,
3126 GList **varargs_callbacks_out)
3129 GList *varargs_callbacks = *varargs_callbacks_out;
3135 GIrNode *node = iter->data;
3139 if (node->type == G_IR_NODE_FUNCTION)
3141 if (((GIrNodeFunction*)node)->is_varargs)
3143 list = g_list_delete_link (list, link);
3146 if (node->type == G_IR_NODE_CALLBACK)
3148 if (((GIrNodeFunction*)node)->is_varargs)
3150 varargs_callbacks = g_list_append (varargs_callbacks,
3152 list = g_list_delete_link (list, link);
3157 *varargs_callbacks_out = varargs_callbacks;
3163 post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out)
3166 GList *varargs_callbacks;
3168 list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out);
3170 varargs_callbacks = *varargs_callbacks_out;
3176 GIrNode *node = iter->data;
3180 if (node->type == G_IR_NODE_FUNCTION)
3183 gboolean function_done = FALSE;
3185 for (param = ((GIrNodeFunction *)node)->parameters;
3187 param = param->next)
3189 GIrNodeParam *node = (GIrNodeParam *)param->data;
3194 if (node->type->is_interface)
3197 for (callback = varargs_callbacks;
3199 callback = callback->next)
3201 if (!strcmp (node->type->interface,
3202 ((GIrNode *)varargs_callbacks->data)->name))
3204 list = g_list_delete_link (list, link);
3205 function_done = TRUE;
3214 *varargs_callbacks_out = varargs_callbacks;
3220 post_filter (GIrModule *module)
3223 GList *varargs_callbacks = NULL;
3225 module->entries = post_filter_varargs_functions (module->entries,
3226 &varargs_callbacks);
3227 iter = module->entries;
3230 GIrNode *node = iter->data;
3234 if (node->type == G_IR_NODE_OBJECT ||
3235 node->type == G_IR_NODE_INTERFACE)
3237 GIrNodeInterface *iface = (GIrNodeInterface*)node;
3238 iface->members = post_filter_varargs_functions (iface->members,
3239 &varargs_callbacks);
3241 else if (node->type == G_IR_NODE_BOXED)
3243 GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
3244 boxed->members = post_filter_varargs_functions (boxed->members,
3245 &varargs_callbacks);
3247 else if (node->type == G_IR_NODE_STRUCT)
3249 GIrNodeStruct *iface = (GIrNodeStruct*)node;
3250 iface->members = post_filter_varargs_functions (iface->members,
3251 &varargs_callbacks);
3253 else if (node->type == G_IR_NODE_UNION)
3255 GIrNodeUnion *iface = (GIrNodeUnion*)node;
3256 iface->members = post_filter_varargs_functions (iface->members,
3257 &varargs_callbacks);
3260 g_list_free (varargs_callbacks);
3264 * g_ir_parser_parse_string:
3265 * @parser: a #GIrParser
3266 * @namespace: the namespace of the string
3267 * @buffer: the data containing the XML
3268 * @length: length of the data
3269 * @error: return location for a #GError, or %NULL
3271 * Parse a string that holds a complete GIR XML file, and return a list of a
3272 * a #GirModule for each <namespace/> element within the file.
3274 * Returns: a newly allocated list of #GIrModule. The modules themselves
3275 * are owned by the #GIrParser and will be freed along with the parser.
3278 g_ir_parser_parse_string (GIrParser *parser,
3279 const gchar *namespace,
3280 const gchar *buffer,
3284 ParseContext ctx = { 0 };
3285 GMarkupParseContext *context;
3287 ctx.parser = parser;
3288 ctx.state = STATE_START;
3289 ctx.namespace = namespace;
3290 ctx.include_modules = NULL;
3291 ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
3292 ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
3294 ctx.dependencies = NULL;
3295 ctx.current_module = NULL;
3297 context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
3299 if (!g_markup_parse_context_parse (context, buffer, length, error))
3302 if (!g_markup_parse_context_end_parse (context, error))
3305 g_markup_parse_context_free (context);
3307 context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL);
3308 if (!g_markup_parse_context_parse (context, buffer, length, error))
3311 if (!g_markup_parse_context_end_parse (context, error))
3314 parser->parsed_modules = g_list_concat (g_list_copy (ctx.modules),
3315 parser->parsed_modules);
3319 if (ctx.modules == NULL)
3321 /* An error occurred before we created a module, so we haven't
3322 * transferred ownership of these hash tables to the module.
3324 if (ctx.aliases != NULL)
3325 g_hash_table_destroy (ctx.aliases);
3326 if (ctx.disguised_structures != NULL)
3327 g_hash_table_destroy (ctx.disguised_structures);
3328 g_list_free (ctx.include_modules);
3331 g_markup_parse_context_free (context);
3337 * g_ir_parser_parse_file:
3338 * @parser: a #GIrParser
3339 * @filename: filename to parse
3340 * @error: return location for a #GError, or %NULL
3342 * Parse GIR XML file, and return a list of a a #GirModule for each
3343 * <namespace/> element within the file.
3345 * Returns: a newly allocated list of #GIrModule. The modules themselves
3346 * are owned by the #GIrParser and will be freed along with the parser.
3349 g_ir_parser_parse_file (GIrParser *parser,
3350 const gchar *filename,
3361 if (!g_str_has_suffix (filename, ".gir"))
3365 G_MARKUP_ERROR_INVALID_CONTENT,
3366 "Expected filename to end with '.gir'");
3370 g_debug ("[parsing] filename %s", filename);
3372 slash = g_strrstr (filename, "/");
3374 namespace = g_strdup (filename);
3376 namespace = g_strdup (slash+1);
3377 namespace[strlen(namespace)-4] = '\0';
3379 /* Remove version */
3380 dash = strstr (namespace, "-");
3384 if (!g_file_get_contents (filename, &buffer, &length, error))
3387 modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error);
3389 for (iter = modules; iter; iter = iter->next)
3391 post_filter ((GIrModule*)iter->data);