1 /* GObject introspection: A parser for the XML GIR format
3 * Copyright (C) 2008 Philip Van Hoof
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
26 #include "girparser.h"
27 #include "girmodule.h"
34 GList *parsed_modules; /* All previously parsed modules */
44 STATE_NAMESPACE, /* 5 */
48 STATE_FUNCTION_RETURN,
49 STATE_FUNCTION_PARAMETERS, /* 10 */
50 STATE_FUNCTION_PARAMETER,
54 STATE_INTERFACE, /* 15 */
55 STATE_INTERFACE_PROPERTY,
56 STATE_INTERFACE_FIELD,
66 STATE_NAMESPACE_CONSTANT,
68 STATE_INTERFACE_CONSTANT,
75 typedef struct _ParseContext ParseContext;
82 ParseState prev_state;
85 GList *include_modules;
88 GHashTable *disguised_structures;
90 const char *namespace;
92 GIrModule *current_module;
94 GIrNode *current_typed;
97 GList *type_parameters;
100 #define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
102 static void start_element_handler (GMarkupParseContext *context,
103 const gchar *element_name,
104 const gchar **attribute_names,
105 const gchar **attribute_values,
108 static void end_element_handler (GMarkupParseContext *context,
109 const gchar *element_name,
112 static void text_handler (GMarkupParseContext *context,
117 static void cleanup (GMarkupParseContext *context,
121 static GMarkupParser markup_parser =
123 start_element_handler,
131 start_alias (GMarkupParseContext *context,
132 const gchar *element_name,
133 const gchar **attribute_names,
134 const gchar **attribute_values,
138 static const gchar *find_attribute (const gchar *name,
139 const gchar **attribute_names,
140 const gchar **attribute_values);
144 g_ir_parser_new (void)
146 GIrParser *parser = g_slice_new0 (GIrParser);
152 g_ir_parser_free (GIrParser *parser)
156 if (parser->includes)
157 g_strfreev (parser->includes);
159 for (l = parser->parsed_modules; l; l = l->next)
160 g_ir_module_free (l->data);
162 g_slice_free (GIrParser, parser);
166 g_ir_parser_set_includes (GIrParser *parser,
167 const gchar *const *includes)
169 if (parser->includes)
170 g_strfreev (parser->includes);
172 parser->includes = g_strdupv ((char **)includes);
176 firstpass_start_element_handler (GMarkupParseContext *context,
177 const gchar *element_name,
178 const gchar **attribute_names,
179 const gchar **attribute_values,
183 ParseContext *ctx = user_data;
185 if (strcmp (element_name, "alias") == 0)
187 start_alias (context, element_name, attribute_names, attribute_values,
190 else if (strcmp (element_name, "record") == 0)
193 const gchar *disguised;
195 name = find_attribute ("name", attribute_names, attribute_values);
196 disguised = find_attribute ("disguised", attribute_names, attribute_values);
198 if (disguised && strcmp (disguised, "1") == 0)
202 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
203 g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
209 firstpass_end_element_handler (GMarkupParseContext *context,
210 const gchar *element_name,
216 static GMarkupParser firstpass_parser =
218 firstpass_start_element_handler,
219 firstpass_end_element_handler,
226 locate_gir (GIrParser *parser,
229 const gchar *const *datadirs;
230 const gchar *const *dir;
233 datadirs = g_get_system_data_dirs ();
235 if (parser->includes != NULL)
237 for (dir = (const gchar *const *)parser->includes; *dir; dir++)
239 path = g_build_filename (*dir, girname, NULL);
240 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
246 for (dir = datadirs; *dir; dir++)
248 path = g_build_filename (*dir, "gir-1.0", girname, NULL);
249 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
257 #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \
259 int line_number, char_number; \
260 g_markup_parse_context_get_position (context, &line_number, &char_number); \
261 g_set_error (error, \
263 G_MARKUP_ERROR_INVALID_CONTENT, \
264 "Line %d, character %d: The attribute '%s' on the element '%s' must be specified", \
265 line_number, char_number, attribute, element); \
269 backtrace_stderr (void)
271 #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
277 size = backtrace (array, 50);
278 strings = (char**) backtrace_symbols (array, size);
280 fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size);
282 for (i = 0; i < size; i++)
283 fprintf (stderr, "%s\n", strings[i]);
285 fprintf (stderr, "--- END BACKTRACE ---\n", size);
293 find_attribute (const gchar *name,
294 const gchar **attribute_names,
295 const gchar **attribute_values)
299 for (i = 0; attribute_names[i] != NULL; i++)
300 if (strcmp (attribute_names[i], name) == 0)
301 return attribute_values[i];
307 state_switch (ParseContext *ctx, ParseState newstate)
309 g_debug ("State: %d", newstate);
310 ctx->prev_state = ctx->state;
311 ctx->state = newstate;
315 pop_node (ParseContext *ctx)
317 g_assert (ctx->node_stack != 0);
319 GSList *top = ctx->node_stack;
320 GIrNode *node = top->data;
322 g_debug ("popping node %d %s", node->type, node->name);
323 ctx->node_stack = top->next;
324 g_slist_free_1 (top);
329 push_node (ParseContext *ctx, GIrNode *node)
331 g_debug ("pushing node %d %s", node->type, node->name);
332 ctx->node_stack = g_slist_prepend (ctx->node_stack, node);
335 static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
336 gboolean in_gobject);
344 static BasicTypeInfo basic_types[] = {
345 { "none", GI_TYPE_TAG_VOID, 0 },
346 { "any", GI_TYPE_TAG_VOID, 1 },
348 { "bool", GI_TYPE_TAG_BOOLEAN, 0 },
349 { "char", GI_TYPE_TAG_INT8, 0 },
350 { "int8", GI_TYPE_TAG_INT8, 0 },
351 { "uint8", GI_TYPE_TAG_UINT8, 0 },
352 { "int16", GI_TYPE_TAG_INT16, 0 },
353 { "uint16", GI_TYPE_TAG_UINT16, 0 },
354 { "int32", GI_TYPE_TAG_INT32, 0 },
355 { "uint32", GI_TYPE_TAG_UINT32, 0 },
356 { "int64", GI_TYPE_TAG_INT64, 0 },
357 { "uint64", GI_TYPE_TAG_UINT64, 0 },
358 { "int", GI_TYPE_TAG_INT, 0 },
359 { "uint", GI_TYPE_TAG_UINT, 0 },
360 { "long", GI_TYPE_TAG_LONG, 0 },
361 { "ulong", GI_TYPE_TAG_ULONG, 0 },
362 { "ssize_t", GI_TYPE_TAG_SSIZE, 0 },
363 { "ssize", GI_TYPE_TAG_SSIZE, 0 },
364 { "size_t", GI_TYPE_TAG_SIZE, 0 },
365 { "size", GI_TYPE_TAG_SIZE, 0 },
366 { "float", GI_TYPE_TAG_FLOAT, 0 },
367 { "double", GI_TYPE_TAG_DOUBLE, 0 },
368 { "time_t", GI_TYPE_TAG_TIME_T, 0 },
369 { "GType", GI_TYPE_TAG_GTYPE, 0 },
370 { "utf8", GI_TYPE_TAG_UTF8, 1 },
371 { "filename", GI_TYPE_TAG_FILENAME,1 },
374 static const BasicTypeInfo *
375 parse_basic (const char *str)
378 gint n_basic = G_N_ELEMENTS (basic_types);
380 for (i = 0; i < n_basic; i++)
382 if (g_str_has_prefix (str, basic_types[i].str))
383 return &(basic_types[i]);
389 parse_type_internal (const gchar *str, char **next, gboolean in_glib,
392 const BasicTypeInfo *basic;
394 char *temporary_type = NULL;
396 type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
398 type->unparsed = g_strdup (str);
400 /* See comment below on GLib.List handling */
401 if (in_gobject && strcmp (str, "Type") == 0)
403 temporary_type = g_strdup ("GLib.Type");
404 str = temporary_type;
407 basic = parse_basic (str);
410 type->is_basic = TRUE;
411 type->tag = basic->tag;
412 type->is_pointer = basic->pointer;
414 str += strlen(basic->str);
418 /* If we're inside GLib, handle "List" etc. by prefixing with
419 * "GLib." so the parsing code below doesn't have to get more
422 if (g_str_has_prefix (str, "List<") ||
423 strcmp (str, "List") == 0)
425 temporary_type = g_strdup_printf ("GLib.List%s", str + 4);
426 str = temporary_type;
428 else if (g_str_has_prefix (str, "SList<") ||
429 strcmp (str, "SList") == 0)
431 temporary_type = g_strdup_printf ("GLib.SList%s", str + 5);
432 str = temporary_type;
434 else if (g_str_has_prefix (str, "HashTable<") ||
435 strcmp (str, "HashTable") == 0)
437 temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9);
438 str = temporary_type;
440 else if (g_str_has_prefix (str, "Error<") ||
441 strcmp (str, "Error") == 0)
443 temporary_type = g_strdup_printf ("GLib.Error%s", str + 5);
444 str = temporary_type;
449 /* found a basic type */;
450 else if (g_str_has_prefix (str, "GLib.List") ||
451 g_str_has_prefix (str, "GLib.SList"))
453 str += strlen ("GLib.");
454 if (g_str_has_prefix (str, "List"))
456 type->tag = GI_TYPE_TAG_GLIST;
457 type->is_glist = TRUE;
458 type->is_pointer = TRUE;
459 str += strlen ("List");
463 type->tag = GI_TYPE_TAG_GSLIST;
464 type->is_gslist = TRUE;
465 type->is_pointer = TRUE;
466 str += strlen ("SList");
469 else if (g_str_has_prefix (str, "GLib.HashTable"))
471 str += strlen ("GLib.");
473 type->tag = GI_TYPE_TAG_GHASH;
474 type->is_ghashtable = TRUE;
475 type->is_pointer = TRUE;
476 str += strlen ("HashTable");
478 else if (g_str_has_prefix (str, "GLib.Error"))
480 str += strlen ("GLib.");
482 type->tag = GI_TYPE_TAG_ERROR;
483 type->is_error = TRUE;
484 type->is_pointer = TRUE;
485 str += strlen ("Error");
492 end = strchr (str, '>');
493 tmp = g_strndup (str, end - str);
494 type->errors = g_strsplit (tmp, ",", 0);
502 type->tag = GI_TYPE_TAG_INTERFACE;
503 type->is_interface = TRUE;
504 const char *start = str;
506 /* must be an interface type */
507 while (g_ascii_isalnum (*str) ||
514 type->interface = g_strndup (start, str - start);
519 g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR);
520 g_free (temporary_type);
524 g_ir_node_free ((GIrNode *)type);
525 g_free (temporary_type);
530 resolve_aliases (ParseContext *ctx, const gchar *type)
534 GSList *seen_values = NULL;
538 if (strchr (type, '.') == NULL)
540 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
549 seen_values = g_slist_prepend (seen_values, (char*)lookup);
550 while (g_hash_table_lookup_extended (ctx->current_module->aliases, lookup, &orig, &value))
552 g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
554 if (g_slist_find_custom (seen_values, lookup,
555 (GCompareFunc)strcmp) != NULL)
557 seen_values = g_slist_prepend (seen_values, (gchar*)lookup);
559 g_slist_free (seen_values);
561 if (lookup == prefixed)
570 is_disguised_structure (ParseContext *ctx, const gchar *type)
576 if (strchr (type, '.') == NULL)
578 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
587 result = g_hash_table_lookup (ctx->current_module->disguised_structures,
596 parse_type (ParseContext *ctx, const gchar *type)
599 const BasicTypeInfo *basic;
600 gboolean in_glib, in_gobject;
602 in_glib = strcmp (ctx->namespace, "GLib") == 0;
603 in_gobject = strcmp (ctx->namespace, "GObject") == 0;
605 /* Do not search aliases for basic types */
606 basic = parse_basic (type);
608 type = resolve_aliases (ctx, type);
610 node = parse_type_internal (type, NULL, in_glib, in_gobject);
612 g_debug ("Parsed type: %s => %d", type, node->tag);
614 g_critical ("Failed to parse type: '%s'", type);
620 start_glib_boxed (GMarkupParseContext *context,
621 const gchar *element_name,
622 const gchar **attribute_names,
623 const gchar **attribute_values,
628 const gchar *typename;
629 const gchar *typeinit;
630 const gchar *deprecated;
633 if (!(strcmp (element_name, "glib:boxed") == 0 &&
634 ctx->state == STATE_NAMESPACE))
637 name = find_attribute ("glib:name", attribute_names, attribute_values);
638 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
639 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
640 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
644 MISSING_ATTRIBUTE (context, error, element_name, "glib:name");
647 else if (typename == NULL)
649 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
652 else if (typeinit == NULL)
654 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
658 boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED);
660 ((GIrNode *)boxed)->name = g_strdup (name);
661 boxed->gtype_name = g_strdup (typename);
662 boxed->gtype_init = g_strdup (typeinit);
664 boxed->deprecated = TRUE;
666 boxed->deprecated = FALSE;
668 push_node (ctx, (GIrNode *)boxed);
669 ctx->current_module->entries =
670 g_list_append (ctx->current_module->entries, boxed);
672 state_switch (ctx, STATE_BOXED);
678 start_function (GMarkupParseContext *context,
679 const gchar *element_name,
680 const gchar **attribute_names,
681 const gchar **attribute_values,
687 const gchar *deprecated;
689 GIrNodeFunction *function;
690 gboolean found = FALSE;
694 case STATE_NAMESPACE:
695 found = (strcmp (element_name, "function") == 0 ||
696 strcmp (element_name, "callback") == 0);
699 found = strcmp (element_name, "function") == 0;
704 found = (found || strcmp (element_name, "constructor") == 0);
706 case STATE_INTERFACE:
708 strcmp (element_name, "method") == 0 ||
709 strcmp (element_name, "callback") == 0);
718 name = find_attribute ("name", attribute_names, attribute_values);
719 symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
720 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
721 throws = find_attribute ("throws", attribute_names, attribute_values);
725 MISSING_ATTRIBUTE (context, error, element_name, "name");
728 else if (strcmp (element_name, "callback") != 0 && symbol == NULL)
730 MISSING_ATTRIBUTE (context, error, element_name, "c:identifier");
734 function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION);
736 ((GIrNode *)function)->name = g_strdup (name);
737 function->symbol = g_strdup (symbol);
738 function->parameters = NULL;
740 function->deprecated = TRUE;
742 function->deprecated = FALSE;
744 if (strcmp (element_name, "method") == 0 ||
745 strcmp (element_name, "constructor") == 0)
747 function->is_method = TRUE;
749 if (strcmp (element_name, "constructor") == 0)
750 function->is_constructor = TRUE;
752 function->is_constructor = FALSE;
756 function->is_method = FALSE;
757 function->is_setter = FALSE;
758 function->is_getter = FALSE;
759 function->is_constructor = FALSE;
760 if (strcmp (element_name, "callback") == 0)
761 ((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
764 if (throws && strcmp (throws, "1") == 0)
765 function->throws = TRUE;
767 function->throws = FALSE;
769 if (ctx->node_stack == NULL)
771 ctx->current_module->entries =
772 g_list_append (ctx->current_module->entries, function);
775 switch (CURRENT_NODE (ctx)->type)
777 case G_IR_NODE_INTERFACE:
778 case G_IR_NODE_OBJECT:
780 GIrNodeInterface *iface;
782 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
783 iface->members = g_list_append (iface->members, function);
786 case G_IR_NODE_BOXED:
790 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
791 boxed->members = g_list_append (boxed->members, function);
794 case G_IR_NODE_STRUCT:
796 GIrNodeStruct *struct_;
798 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
799 struct_->members = g_list_append (struct_->members, function); }
801 case G_IR_NODE_UNION:
803 GIrNodeUnion *union_;
805 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
806 union_->members = g_list_append (union_->members, function);
810 g_assert_not_reached ();
813 push_node(ctx, (GIrNode *)function);
814 state_switch (ctx, STATE_FUNCTION);
820 parse_param_transfer (GIrNodeParam *param, const gchar *transfer)
822 if (transfer == NULL)
824 g_warning ("required attribute 'transfer-ownership' missing");
826 else if (strcmp (transfer, "none") == 0)
828 param->transfer = FALSE;
829 param->shallow_transfer = FALSE;
831 else if (strcmp (transfer, "container") == 0)
833 param->transfer = FALSE;
834 param->shallow_transfer = TRUE;
836 else if (strcmp (transfer, "full") == 0)
838 param->transfer = TRUE;
839 param->shallow_transfer = FALSE;
843 g_warning ("Unknown transfer-ownership value: %s", transfer);
848 start_parameter (GMarkupParseContext *context,
849 const gchar *element_name,
850 const gchar **attribute_names,
851 const gchar **attribute_values,
856 const gchar *direction;
859 const gchar *optional;
860 const gchar *allow_none;
861 const gchar *transfer;
863 const gchar *closure;
864 const gchar *destroy;
867 if (!(strcmp (element_name, "parameter") == 0 &&
868 ctx->state == STATE_FUNCTION_PARAMETERS))
871 name = find_attribute ("name", attribute_names, attribute_values);
872 direction = find_attribute ("direction", attribute_names, attribute_values);
873 retval = find_attribute ("retval", attribute_names, attribute_values);
874 dipper = find_attribute ("dipper", attribute_names, attribute_values);
875 optional = find_attribute ("optional", attribute_names, attribute_values);
876 allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
877 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
878 scope = find_attribute ("scope", attribute_names, attribute_values);
879 closure = find_attribute ("closure", attribute_names, attribute_values);
880 destroy = find_attribute ("destroy", attribute_names, attribute_values);
885 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
887 ctx->current_typed = (GIrNode*) param;
888 ctx->current_typed->name = g_strdup (name);
890 state_switch (ctx, STATE_FUNCTION_PARAMETER);
892 if (direction && strcmp (direction, "out") == 0)
897 else if (direction && strcmp (direction, "inout") == 0)
908 if (retval && strcmp (retval, "1") == 0)
909 param->retval = TRUE;
911 param->retval = FALSE;
913 if (dipper && strcmp (dipper, "1") == 0)
914 param->dipper = TRUE;
916 param->dipper = FALSE;
918 if (optional && strcmp (optional, "1") == 0)
919 param->optional = TRUE;
921 param->optional = FALSE;
923 if (allow_none && strcmp (allow_none, "1") == 0)
924 param->allow_none = TRUE;
926 param->allow_none = FALSE;
928 parse_param_transfer (param, transfer);
930 if (scope && strcmp (scope, "call") == 0)
931 param->scope = GI_SCOPE_TYPE_CALL;
932 else if (scope && strcmp (scope, "async") == 0)
933 param->scope = GI_SCOPE_TYPE_ASYNC;
934 else if (scope && strcmp (scope, "notified") == 0)
935 param->scope = GI_SCOPE_TYPE_NOTIFIED;
937 param->scope = GI_SCOPE_TYPE_INVALID;
939 param->closure = closure ? atoi (closure) : -1;
940 param->destroy = destroy ? atoi (destroy) : -1;
942 ((GIrNode *)param)->name = g_strdup (name);
944 switch (CURRENT_NODE (ctx)->type)
946 case G_IR_NODE_FUNCTION:
947 case G_IR_NODE_CALLBACK:
949 GIrNodeFunction *func;
951 func = (GIrNodeFunction *)CURRENT_NODE (ctx);
952 func->parameters = g_list_append (func->parameters, param);
955 case G_IR_NODE_SIGNAL:
957 GIrNodeSignal *signal;
959 signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
960 signal->parameters = g_list_append (signal->parameters, param);
963 case G_IR_NODE_VFUNC:
967 vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
968 vfunc->parameters = g_list_append (vfunc->parameters, param);
972 g_assert_not_reached ();
979 start_field (GMarkupParseContext *context,
980 const gchar *element_name,
981 const gchar **attribute_names,
982 const gchar **attribute_values,
987 const gchar *readable;
988 const gchar *writable;
999 case STATE_INTERFACE:
1005 if (strcmp (element_name, "field") != 0)
1008 name = find_attribute ("name", attribute_names, attribute_values);
1009 readable = find_attribute ("readable", attribute_names, attribute_values);
1010 writable = find_attribute ("writable", attribute_names, attribute_values);
1011 bits = find_attribute ("bits", attribute_names, attribute_values);
1012 branch = find_attribute ("branch", attribute_names, attribute_values);
1016 MISSING_ATTRIBUTE (context, error, element_name, "name");
1020 field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD);
1021 ctx->current_typed = (GIrNode*) field;
1022 ((GIrNode *)field)->name = g_strdup (name);
1023 /* Fields are assumed to be read-only.
1024 * (see also girwriter.py and generate.c)
1026 field->readable = readable == NULL || strcmp (readable, "0") == 0;
1027 field->writable = writable != NULL && strcmp (writable, "1") == 0;
1030 field->bits = atoi (bits);
1034 switch (CURRENT_NODE (ctx)->type)
1036 case G_IR_NODE_OBJECT:
1038 GIrNodeInterface *iface;
1040 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1041 iface->members = g_list_append (iface->members, field);
1042 state_switch (ctx, STATE_CLASS_FIELD);
1045 case G_IR_NODE_INTERFACE:
1047 GIrNodeInterface *iface;
1049 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1050 iface->members = g_list_append (iface->members, field);
1051 state_switch (ctx, STATE_INTERFACE_FIELD);
1054 case G_IR_NODE_BOXED:
1056 GIrNodeBoxed *boxed;
1058 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
1059 boxed->members = g_list_append (boxed->members, field);
1060 state_switch (ctx, STATE_BOXED_FIELD);
1063 case G_IR_NODE_STRUCT:
1065 GIrNodeStruct *struct_;
1067 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
1068 struct_->members = g_list_append (struct_->members, field);
1069 state_switch (ctx, STATE_STRUCT_FIELD);
1072 case G_IR_NODE_UNION:
1074 GIrNodeUnion *union_;
1076 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
1077 union_->members = g_list_append (union_->members, field);
1080 GIrNodeConstant *constant;
1082 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1083 ((GIrNode *)constant)->name = g_strdup (name);
1084 constant->value = g_strdup (branch);
1085 constant->type = union_->discriminator_type;
1086 constant->deprecated = FALSE;
1088 union_->discriminators = g_list_append (union_->discriminators, constant);
1090 state_switch (ctx, STATE_UNION_FIELD);
1094 g_assert_not_reached ();
1101 start_alias (GMarkupParseContext *context,
1102 const gchar *element_name,
1103 const gchar **attribute_names,
1104 const gchar **attribute_values,
1109 const gchar *target;
1113 name = find_attribute ("name", attribute_names, attribute_values);
1116 MISSING_ATTRIBUTE (context, error, element_name, "name");
1120 target = find_attribute ("target", attribute_names, attribute_values);
1123 MISSING_ATTRIBUTE (context, error, element_name, "target");
1127 value = g_strdup (target);
1128 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
1129 if (!strchr (target, '.'))
1131 const BasicTypeInfo *basic = parse_basic (target);
1135 /* For non-basic types, re-qualify the interface */
1136 value = g_strdup_printf ("%s.%s", ctx->namespace, target);
1139 g_hash_table_replace (ctx->aliases, key, value);
1145 start_enum (GMarkupParseContext *context,
1146 const gchar *element_name,
1147 const gchar **attribute_names,
1148 const gchar **attribute_values,
1152 if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
1153 (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))
1156 const gchar *typename;
1157 const gchar *typeinit;
1158 const gchar *deprecated;
1160 name = find_attribute ("name", attribute_names, attribute_values);
1161 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1162 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1163 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1166 MISSING_ATTRIBUTE (context, error, element_name, "name");
1171 if (strcmp (element_name, "enumeration") == 0)
1172 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM);
1174 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS);
1175 ((GIrNode *)enum_)->name = g_strdup (name);
1176 enum_->gtype_name = g_strdup (typename);
1177 enum_->gtype_init = g_strdup (typeinit);
1179 enum_->deprecated = TRUE;
1181 enum_->deprecated = FALSE;
1183 push_node (ctx, (GIrNode *) enum_);
1184 ctx->current_module->entries =
1185 g_list_append (ctx->current_module->entries, enum_);
1187 state_switch (ctx, STATE_ENUM);
1196 start_property (GMarkupParseContext *context,
1197 const gchar *element_name,
1198 const gchar **attribute_names,
1199 const gchar **attribute_values,
1203 if (strcmp (element_name, "property") == 0 &&
1204 (ctx->state == STATE_CLASS ||
1205 ctx->state == STATE_INTERFACE))
1208 const gchar *readable;
1209 const gchar *writable;
1210 const gchar *construct;
1211 const gchar *construct_only;
1213 name = find_attribute ("name", attribute_names, attribute_values);
1214 readable = find_attribute ("readable", attribute_names, attribute_values);
1215 writable = find_attribute ("writable", attribute_names, attribute_values);
1216 construct = find_attribute ("construct", attribute_names, attribute_values);
1217 construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
1220 MISSING_ATTRIBUTE (context, error, element_name, "name");
1223 GIrNodeProperty *property;
1224 GIrNodeInterface *iface;
1226 property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
1227 ctx->current_typed = (GIrNode*) property;
1229 ((GIrNode *)property)->name = g_strdup (name);
1231 /* Assume properties are readable */
1232 if (readable == NULL || strcmp (readable, "1") == 0)
1233 property->readable = TRUE;
1235 property->readable = FALSE;
1236 if (writable && strcmp (writable, "1") == 0)
1237 property->writable = TRUE;
1239 property->writable = FALSE;
1240 if (construct && strcmp (construct, "1") == 0)
1241 property->construct = TRUE;
1243 property->construct = FALSE;
1244 if (construct_only && strcmp (construct_only, "1") == 0)
1245 property->construct_only = TRUE;
1247 property->construct_only = FALSE;
1249 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1250 iface->members = g_list_append (iface->members, property);
1252 if (ctx->state == STATE_CLASS)
1253 state_switch (ctx, STATE_CLASS_PROPERTY);
1254 else if (ctx->state == STATE_INTERFACE)
1255 state_switch (ctx, STATE_INTERFACE_PROPERTY);
1257 g_assert_not_reached ();
1266 parse_value (const gchar *str)
1270 /* FIXME just a quick hack */
1271 shift_op = strstr (str, "<<");
1277 base = strtol (str, NULL, 10);
1278 shift = strtol (shift_op + 3, NULL, 10);
1280 return base << shift;
1283 return strtol (str, NULL, 10);
1289 start_member (GMarkupParseContext *context,
1290 const gchar *element_name,
1291 const gchar **attribute_names,
1292 const gchar **attribute_values,
1296 if (strcmp (element_name, "member") == 0 &&
1297 ctx->state == STATE_ENUM)
1301 const gchar *deprecated;
1303 name = find_attribute ("name", attribute_names, attribute_values);
1304 value = find_attribute ("value", attribute_names, attribute_values);
1305 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1308 MISSING_ATTRIBUTE (context, error, element_name, "name");
1312 GIrNodeValue *value_;
1314 value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
1316 ((GIrNode *)value_)->name = g_strdup (name);
1318 value_->value = parse_value (value);
1321 value_->deprecated = TRUE;
1323 value_->deprecated = FALSE;
1325 enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx);
1326 enum_->values = g_list_append (enum_->values, value_);
1335 start_constant (GMarkupParseContext *context,
1336 const gchar *element_name,
1337 const gchar **attribute_names,
1338 const gchar **attribute_values,
1342 if (strcmp (element_name, "constant") == 0 &&
1343 (ctx->state == STATE_NAMESPACE ||
1344 ctx->state == STATE_CLASS ||
1345 ctx->state == STATE_INTERFACE))
1349 const gchar *deprecated;
1351 name = find_attribute ("name", attribute_names, attribute_values);
1352 value = find_attribute ("value", attribute_names, attribute_values);
1353 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1356 MISSING_ATTRIBUTE (context, error, element_name, "name");
1357 else if (value == NULL)
1358 MISSING_ATTRIBUTE (context, error, element_name, "value");
1361 GIrNodeConstant *constant;
1363 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1365 ((GIrNode *)constant)->name = g_strdup (name);
1366 constant->value = g_strdup (value);
1368 ctx->current_typed = (GIrNode*) constant;
1371 constant->deprecated = TRUE;
1373 constant->deprecated = FALSE;
1375 if (ctx->state == STATE_NAMESPACE)
1377 push_node (ctx, (GIrNode *) constant);
1378 ctx->current_module->entries =
1379 g_list_append (ctx->current_module->entries, constant);
1383 GIrNodeInterface *iface;
1385 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1386 iface->members = g_list_append (iface->members, constant);
1391 case STATE_NAMESPACE:
1392 state_switch (ctx, STATE_NAMESPACE_CONSTANT);
1395 state_switch (ctx, STATE_CLASS_CONSTANT);
1397 case STATE_INTERFACE:
1398 state_switch (ctx, STATE_INTERFACE_CONSTANT);
1401 g_assert_not_reached ();
1412 start_errordomain (GMarkupParseContext *context,
1413 const gchar *element_name,
1414 const gchar **attribute_names,
1415 const gchar **attribute_values,
1419 if (strcmp (element_name, "errordomain") == 0 &&
1420 ctx->state == STATE_NAMESPACE)
1423 const gchar *getquark;
1425 const gchar *deprecated;
1427 name = find_attribute ("name", attribute_names, attribute_values);
1428 getquark = find_attribute ("get-quark", attribute_names, attribute_values);
1429 codes = find_attribute ("codes", attribute_names, attribute_values);
1430 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1433 MISSING_ATTRIBUTE (context, error, element_name, "name");
1434 else if (getquark == NULL)
1435 MISSING_ATTRIBUTE (context, error, element_name, "getquark");
1436 else if (codes == NULL)
1437 MISSING_ATTRIBUTE (context, error, element_name, "codes");
1440 GIrNodeErrorDomain *domain;
1442 domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
1444 ((GIrNode *)domain)->name = g_strdup (name);
1445 domain->getquark = g_strdup (getquark);
1446 domain->codes = g_strdup (codes);
1449 domain->deprecated = TRUE;
1451 domain->deprecated = FALSE;
1453 push_node (ctx, (GIrNode *) domain);
1454 ctx->current_module->entries =
1455 g_list_append (ctx->current_module->entries, domain);
1457 state_switch (ctx, STATE_ERRORDOMAIN);
1466 start_interface (GMarkupParseContext *context,
1467 const gchar *element_name,
1468 const gchar **attribute_names,
1469 const gchar **attribute_values,
1473 if (strcmp (element_name, "interface") == 0 &&
1474 ctx->state == STATE_NAMESPACE)
1477 const gchar *typename;
1478 const gchar *typeinit;
1479 const gchar *deprecated;
1480 const gchar *glib_type_struct;
1482 name = find_attribute ("name", attribute_names, attribute_values);
1483 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1484 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1485 glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values);
1486 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1489 MISSING_ATTRIBUTE (context, error, element_name, "name");
1490 else if (typename == NULL)
1491 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1492 else if (typeinit == NULL)
1493 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1496 GIrNodeInterface *iface;
1498 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE);
1499 ((GIrNode *)iface)->name = g_strdup (name);
1500 iface->gtype_name = g_strdup (typename);
1501 iface->gtype_init = g_strdup (typeinit);
1502 iface->glib_type_struct = g_strdup (glib_type_struct);
1504 iface->deprecated = TRUE;
1506 iface->deprecated = FALSE;
1508 push_node (ctx, (GIrNode *) iface);
1509 ctx->current_module->entries =
1510 g_list_append (ctx->current_module->entries, iface);
1512 state_switch (ctx, STATE_INTERFACE);
1522 start_class (GMarkupParseContext *context,
1523 const gchar *element_name,
1524 const gchar **attribute_names,
1525 const gchar **attribute_values,
1529 if (strcmp (element_name, "class") == 0 &&
1530 ctx->state == STATE_NAMESPACE)
1533 const gchar *parent;
1534 const gchar *glib_type_struct;
1535 const gchar *typename;
1536 const gchar *typeinit;
1537 const gchar *deprecated;
1538 const gchar *abstract;
1540 name = find_attribute ("name", attribute_names, attribute_values);
1541 parent = find_attribute ("parent", attribute_names, attribute_values);
1542 glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values);
1543 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1544 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1545 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1546 abstract = find_attribute ("abstract", attribute_names, attribute_values);
1549 MISSING_ATTRIBUTE (context, error, element_name, "name");
1550 else if (typename == NULL)
1551 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1552 else if (typeinit == NULL && strcmp (typename, "GObject"))
1553 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1556 GIrNodeInterface *iface;
1558 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT);
1559 ((GIrNode *)iface)->name = g_strdup (name);
1560 iface->gtype_name = g_strdup (typename);
1561 iface->gtype_init = g_strdup (typeinit);
1562 iface->parent = g_strdup (parent);
1563 iface->glib_type_struct = g_strdup (glib_type_struct);
1565 iface->deprecated = TRUE;
1567 iface->deprecated = FALSE;
1569 iface->abstract = abstract && strcmp (abstract, "1") == 0;
1571 push_node (ctx, (GIrNode *) iface);
1572 ctx->current_module->entries =
1573 g_list_append (ctx->current_module->entries, iface);
1575 state_switch (ctx, STATE_CLASS);
1584 start_type (GMarkupParseContext *context,
1585 const gchar *element_name,
1586 const gchar **attribute_names,
1587 const gchar **attribute_values,
1594 gboolean is_varargs;
1595 GIrNodeType *typenode;
1597 is_array = strcmp (element_name, "array") == 0;
1598 is_varargs = strcmp (element_name, "varargs") == 0;
1600 if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
1603 if (ctx->state == STATE_TYPE)
1606 ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters);
1607 ctx->type_parameters = NULL;
1609 else if (ctx->state == STATE_FUNCTION_PARAMETER ||
1610 ctx->state == STATE_FUNCTION_RETURN ||
1611 ctx->state == STATE_STRUCT_FIELD ||
1612 ctx->state == STATE_UNION_FIELD ||
1613 ctx->state == STATE_CLASS_PROPERTY ||
1614 ctx->state == STATE_CLASS_FIELD ||
1615 ctx->state == STATE_INTERFACE_FIELD ||
1616 ctx->state == STATE_INTERFACE_PROPERTY ||
1617 ctx->state == STATE_BOXED_FIELD ||
1618 ctx->state == STATE_NAMESPACE_CONSTANT ||
1619 ctx->state == STATE_CLASS_CONSTANT ||
1620 ctx->state == STATE_INTERFACE_CONSTANT
1623 state_switch (ctx, STATE_TYPE);
1624 ctx->type_depth = 1;
1627 switch (CURRENT_NODE (ctx)->type)
1629 case G_IR_NODE_FUNCTION:
1630 case G_IR_NODE_CALLBACK:
1632 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1633 func->is_varargs = TRUE;
1636 case G_IR_NODE_VFUNC:
1638 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1639 vfunc->is_varargs = TRUE;
1642 /* list others individually rather than with default: so that compiler
1643 * warns if new node types are added without adding them to the switch
1645 case G_IR_NODE_INVALID:
1646 case G_IR_NODE_ENUM:
1647 case G_IR_NODE_FLAGS:
1648 case G_IR_NODE_CONSTANT:
1649 case G_IR_NODE_ERROR_DOMAIN:
1650 case G_IR_NODE_PARAM:
1651 case G_IR_NODE_TYPE:
1652 case G_IR_NODE_PROPERTY:
1653 case G_IR_NODE_SIGNAL:
1654 case G_IR_NODE_VALUE:
1655 case G_IR_NODE_FIELD:
1656 case G_IR_NODE_XREF:
1657 case G_IR_NODE_STRUCT:
1658 case G_IR_NODE_BOXED:
1659 case G_IR_NODE_OBJECT:
1660 case G_IR_NODE_INTERFACE:
1661 case G_IR_NODE_UNION:
1662 g_assert_not_reached ();
1666 ctx->type_stack = NULL;
1667 ctx->type_parameters = NULL;
1670 if (!ctx->current_typed)
1674 G_MARKUP_ERROR_INVALID_CONTENT,
1675 "The element <type> is invalid here");
1688 typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
1690 typenode->tag = GI_TYPE_TAG_ARRAY;
1691 typenode->is_pointer = TRUE;
1692 typenode->is_array = TRUE;
1694 zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
1695 len = find_attribute ("length", attribute_names, attribute_values);
1696 size = find_attribute ("fixed-size", attribute_names, attribute_values);
1698 typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0);
1699 typenode->has_length = len != NULL;
1700 typenode->length = typenode->has_length ? atoi (len) : -1;
1702 typenode->has_size = size != NULL;
1703 typenode->size = typenode->has_size ? atoi (size) : -1;
1708 name = find_attribute ("name", attribute_names, attribute_values);
1711 MISSING_ATTRIBUTE (context, error, element_name, "name");
1714 ctype = find_attribute ("c:type", attribute_names, attribute_values);
1717 const char *cp = ctype + strlen(ctype) - 1;
1718 while (cp > ctype && *cp-- == '*')
1722 if (ctx->current_typed->type == G_IR_NODE_PARAM &&
1723 ((GIrNodeParam *)ctx->current_typed)->out &&
1727 typenode = parse_type (ctx, name);
1729 /* A 'disguised' structure is one where the c:type is a typedef that
1730 * doesn't look like a pointer, but is internally.
1732 if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
1733 is_disguised_structure (ctx, typenode->interface))
1736 if (pointer_depth > 0)
1737 typenode->is_pointer = TRUE;
1740 ctx->type_parameters = g_list_append (ctx->type_parameters, typenode);
1746 end_type_top (ParseContext *ctx)
1748 GIrNodeType *typenode;
1750 if (!ctx->type_parameters)
1753 typenode = (GIrNodeType*)ctx->type_parameters->data;
1755 /* Default to pointer for unspecified containers */
1756 if (typenode->tag == GI_TYPE_TAG_ARRAY ||
1757 typenode->tag == GI_TYPE_TAG_GLIST ||
1758 typenode->tag == GI_TYPE_TAG_GSLIST)
1760 if (typenode->parameter_type1 == NULL)
1761 typenode->parameter_type1 = parse_type (ctx, "any");
1763 else if (typenode->tag == GI_TYPE_TAG_GHASH)
1765 if (typenode->parameter_type1 == NULL)
1767 typenode->parameter_type1 = parse_type (ctx, "any");
1768 typenode->parameter_type2 = parse_type (ctx, "any");
1772 switch (ctx->current_typed->type)
1774 case G_IR_NODE_PARAM:
1776 GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed;
1777 param->type = typenode;
1780 case G_IR_NODE_FIELD:
1782 GIrNodeField *field = (GIrNodeField *)ctx->current_typed;
1783 field->type = typenode;
1786 case G_IR_NODE_PROPERTY:
1788 GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed;
1789 property->type = typenode;
1792 case G_IR_NODE_CONSTANT:
1794 GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed;
1795 constant->type = typenode;
1799 g_printerr("current node is %d\n", CURRENT_NODE (ctx)->type);
1800 g_assert_not_reached ();
1802 g_list_free (ctx->type_parameters);
1805 ctx->type_depth = 0;
1806 ctx->type_parameters = NULL;
1807 ctx->current_typed = NULL;
1811 end_type_recurse (ParseContext *ctx)
1813 GIrNodeType *parent;
1814 GIrNodeType *param = NULL;
1816 parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data;
1817 if (ctx->type_parameters)
1818 param = (GIrNodeType *) ctx->type_parameters->data;
1820 if (parent->tag == GI_TYPE_TAG_ARRAY ||
1821 parent->tag == GI_TYPE_TAG_GLIST ||
1822 parent->tag == GI_TYPE_TAG_GSLIST)
1824 g_assert (param != NULL);
1826 if (parent->parameter_type1 == NULL)
1827 parent->parameter_type1 = param;
1829 g_assert_not_reached ();
1831 else if (parent->tag == GI_TYPE_TAG_GHASH)
1833 g_assert (param != NULL);
1835 if (parent->parameter_type1 == NULL)
1836 parent->parameter_type1 = param;
1837 else if (parent->parameter_type2 == NULL)
1838 parent->parameter_type2 = param;
1840 g_assert_not_reached ();
1842 g_list_free (ctx->type_parameters);
1843 ctx->type_parameters = (GList *)ctx->type_stack->data;
1844 ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
1848 end_type (ParseContext *ctx)
1850 if (ctx->type_depth == 1)
1853 state_switch (ctx, ctx->prev_state);
1857 end_type_recurse (ctx);
1863 start_attribute (GMarkupParseContext *context,
1864 const gchar *element_name,
1865 const gchar **attribute_names,
1866 const gchar **attribute_values,
1874 if (strcmp (element_name, "attribute") != 0 || ctx->node_stack == NULL)
1877 name = find_attribute ("name", attribute_names, attribute_values);
1878 value = find_attribute ("value", attribute_names, attribute_values);
1882 MISSING_ATTRIBUTE (context, error, element_name, "name");
1887 MISSING_ATTRIBUTE (context, error, element_name, "value");
1891 state_switch (ctx, STATE_ATTRIBUTE);
1893 curnode = CURRENT_NODE (ctx);
1895 g_hash_table_insert (curnode->attributes, g_strdup (name), g_strdup (value));
1901 start_return_value (GMarkupParseContext *context,
1902 const gchar *element_name,
1903 const gchar **attribute_names,
1904 const gchar **attribute_values,
1908 if (strcmp (element_name, "return-value") == 0 &&
1909 ctx->state == STATE_FUNCTION)
1911 GIrNodeParam *param;
1912 const gchar *transfer;
1914 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
1917 param->retval = TRUE;
1919 ctx->current_typed = (GIrNode*) param;
1921 state_switch (ctx, STATE_FUNCTION_RETURN);
1923 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1924 parse_param_transfer (param, transfer);
1926 switch (CURRENT_NODE (ctx)->type)
1928 case G_IR_NODE_FUNCTION:
1929 case G_IR_NODE_CALLBACK:
1931 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1932 func->result = param;
1935 case G_IR_NODE_SIGNAL:
1937 GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
1938 signal->result = param;
1941 case G_IR_NODE_VFUNC:
1943 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1944 vfunc->result = param;
1948 g_assert_not_reached ();
1958 start_implements (GMarkupParseContext *context,
1959 const gchar *element_name,
1960 const gchar **attribute_names,
1961 const gchar **attribute_values,
1965 GIrNodeInterface *iface;
1968 if (strcmp (element_name, "implements") != 0 ||
1969 !(ctx->state == STATE_CLASS))
1972 state_switch (ctx, STATE_IMPLEMENTS);
1974 name = find_attribute ("name", attribute_names, attribute_values);
1977 MISSING_ATTRIBUTE (context, error, element_name, "name");
1981 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1982 iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
1988 start_glib_signal (GMarkupParseContext *context,
1989 const gchar *element_name,
1990 const gchar **attribute_names,
1991 const gchar **attribute_values,
1995 if (strcmp (element_name, "glib:signal") == 0 &&
1996 (ctx->state == STATE_CLASS ||
1997 ctx->state == STATE_INTERFACE))
2001 const gchar *no_recurse;
2002 const gchar *detailed;
2003 const gchar *action;
2004 const gchar *no_hooks;
2005 const gchar *has_class_closure;
2007 name = find_attribute ("name", attribute_names, attribute_values);
2008 when = find_attribute ("when", attribute_names, attribute_values);
2009 no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values);
2010 detailed = find_attribute ("detailed", attribute_names, attribute_values);
2011 action = find_attribute ("action", attribute_names, attribute_values);
2012 no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values);
2013 has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values);
2016 MISSING_ATTRIBUTE (context, error, element_name, "name");
2019 GIrNodeInterface *iface;
2020 GIrNodeSignal *signal;
2022 signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
2024 ((GIrNode *)signal)->name = g_strdup (name);
2026 signal->run_first = FALSE;
2027 signal->run_last = FALSE;
2028 signal->run_cleanup = FALSE;
2029 if (when == NULL || strcmp (when, "LAST") == 0)
2030 signal->run_last = TRUE;
2031 else if (strcmp (when, "FIRST") == 0)
2032 signal->run_first = TRUE;
2034 signal->run_cleanup = TRUE;
2036 if (no_recurse && strcmp (no_recurse, "1") == 0)
2037 signal->no_recurse = TRUE;
2039 signal->no_recurse = FALSE;
2040 if (detailed && strcmp (detailed, "1") == 0)
2041 signal->detailed = TRUE;
2043 signal->detailed = FALSE;
2044 if (action && strcmp (action, "1") == 0)
2045 signal->action = TRUE;
2047 signal->action = FALSE;
2048 if (no_hooks && strcmp (no_hooks, "1") == 0)
2049 signal->no_hooks = TRUE;
2051 signal->no_hooks = FALSE;
2052 if (has_class_closure && strcmp (has_class_closure, "1") == 0)
2053 signal->has_class_closure = TRUE;
2055 signal->has_class_closure = FALSE;
2057 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2058 iface->members = g_list_append (iface->members, signal);
2060 push_node (ctx, (GIrNode *)signal);
2061 state_switch (ctx, STATE_FUNCTION);
2070 start_vfunc (GMarkupParseContext *context,
2071 const gchar *element_name,
2072 const gchar **attribute_names,
2073 const gchar **attribute_values,
2077 if (strcmp (element_name, "virtual-method") == 0 &&
2078 (ctx->state == STATE_CLASS ||
2079 ctx->state == STATE_INTERFACE))
2082 const gchar *must_chain_up;
2083 const gchar *override;
2084 const gchar *is_class_closure;
2085 const gchar *offset;
2086 const gchar *invoker;
2088 name = find_attribute ("name", attribute_names, attribute_values);
2089 must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values);
2090 override = find_attribute ("override", attribute_names, attribute_values);
2091 is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values);
2092 offset = find_attribute ("offset", attribute_names, attribute_values);
2093 invoker = find_attribute ("invoker", attribute_names, attribute_values);
2096 MISSING_ATTRIBUTE (context, error, element_name, "name");
2099 GIrNodeInterface *iface;
2100 GIrNodeVFunc *vfunc;
2102 vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
2104 ((GIrNode *)vfunc)->name = g_strdup (name);
2106 if (must_chain_up && strcmp (must_chain_up, "1") == 0)
2107 vfunc->must_chain_up = TRUE;
2109 vfunc->must_chain_up = FALSE;
2111 if (override && strcmp (override, "always") == 0)
2113 vfunc->must_be_implemented = TRUE;
2114 vfunc->must_not_be_implemented = FALSE;
2116 else if (override && strcmp (override, "never") == 0)
2118 vfunc->must_be_implemented = FALSE;
2119 vfunc->must_not_be_implemented = TRUE;
2123 vfunc->must_be_implemented = FALSE;
2124 vfunc->must_not_be_implemented = FALSE;
2127 if (is_class_closure && strcmp (is_class_closure, "1") == 0)
2128 vfunc->is_class_closure = TRUE;
2130 vfunc->is_class_closure = FALSE;
2133 vfunc->offset = atoi (offset);
2137 vfunc->invoker = g_strdup (invoker);
2139 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2140 iface->members = g_list_append (iface->members, vfunc);
2142 push_node (ctx, (GIrNode *)vfunc);
2143 state_switch (ctx, STATE_FUNCTION);
2153 start_struct (GMarkupParseContext *context,
2154 const gchar *element_name,
2155 const gchar **attribute_names,
2156 const gchar **attribute_values,
2160 if (strcmp (element_name, "record") == 0 &&
2161 (ctx->state == STATE_NAMESPACE ||
2162 ctx->state == STATE_UNION ||
2163 ctx->state == STATE_STRUCT ||
2164 ctx->state == STATE_CLASS))
2167 const gchar *deprecated;
2168 const gchar *disguised;
2169 const gchar *gtype_name;
2170 const gchar *gtype_init;
2171 const gchar *gtype_struct;
2172 GIrNodeStruct *struct_;
2174 name = find_attribute ("name", attribute_names, attribute_values);
2175 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2176 disguised = find_attribute ("disguised", attribute_names, attribute_values);
2177 gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
2178 gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
2179 gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values);
2181 if (name == NULL && ctx->node_stack == NULL)
2183 MISSING_ATTRIBUTE (context, error, element_name, "name");
2186 if ((gtype_name == NULL && gtype_init != NULL))
2188 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
2191 if ((gtype_name != NULL && gtype_init == NULL))
2193 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
2197 struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
2199 ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
2201 struct_->deprecated = TRUE;
2203 struct_->deprecated = FALSE;
2205 if (disguised && strcmp (disguised, "1") == 0)
2206 struct_->disguised = TRUE;
2208 struct_->is_gtype_struct = gtype_struct != NULL;
2210 struct_->gtype_name = g_strdup (gtype_name);
2211 struct_->gtype_init = g_strdup (gtype_init);
2213 if (ctx->node_stack == NULL)
2214 ctx->current_module->entries =
2215 g_list_append (ctx->current_module->entries, struct_);
2216 push_node (ctx, (GIrNode *)struct_);
2218 state_switch (ctx, STATE_STRUCT);
2226 start_union (GMarkupParseContext *context,
2227 const gchar *element_name,
2228 const gchar **attribute_names,
2229 const gchar **attribute_values,
2233 if (strcmp (element_name, "union") == 0 &&
2234 (ctx->state == STATE_NAMESPACE ||
2235 ctx->state == STATE_UNION ||
2236 ctx->state == STATE_STRUCT ||
2237 ctx->state == STATE_CLASS))
2240 const gchar *deprecated;
2241 const gchar *typename;
2242 const gchar *typeinit;
2244 name = find_attribute ("name", attribute_names, attribute_values);
2245 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2246 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
2247 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
2249 if (name == NULL && ctx->node_stack == NULL)
2250 MISSING_ATTRIBUTE (context, error, element_name, "name");
2253 GIrNodeUnion *union_;
2255 union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
2257 ((GIrNode *)union_)->name = g_strdup (name ? name : "");
2258 union_->gtype_name = g_strdup (typename);
2259 union_->gtype_init = g_strdup (typeinit);
2261 union_->deprecated = TRUE;
2263 union_->deprecated = FALSE;
2265 if (ctx->node_stack == NULL)
2266 ctx->current_module->entries =
2267 g_list_append (ctx->current_module->entries, union_);
2268 push_node (ctx, (GIrNode *)union_);
2270 state_switch (ctx, STATE_UNION);
2278 start_discriminator (GMarkupParseContext *context,
2279 const gchar *element_name,
2280 const gchar **attribute_names,
2281 const gchar **attribute_values,
2285 if (strcmp (element_name, "discriminator") == 0 &&
2286 ctx->state == STATE_UNION)
2289 const gchar *offset;
2291 type = find_attribute ("type", attribute_names, attribute_values);
2292 offset = find_attribute ("offset", attribute_names, attribute_values);
2294 MISSING_ATTRIBUTE (context, error, element_name, "type");
2295 else if (offset == NULL)
2296 MISSING_ATTRIBUTE (context, error, element_name, "offset");
2298 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type
2299 = parse_type (ctx, type);
2300 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset
2311 parse_include (GMarkupParseContext *context,
2314 const char *version,
2319 gchar *girpath, *girname;
2320 gboolean success = FALSE;
2324 for (l = ctx->parser->parsed_modules; l; l = l->next)
2326 GIrModule *m = l->data;
2328 if (strcmp (m->name, name) == 0)
2330 if (strcmp (m->version, version) == 0)
2332 ctx->include_modules = g_list_prepend (ctx->include_modules, m);
2340 G_MARKUP_ERROR_INVALID_CONTENT,
2341 "Module '%s' imported with conflicting versions '%s' and '%s'",
2342 name, m->version, version);
2348 girname = g_strdup_printf ("%s-%s.gir", name, version);
2349 girpath = locate_gir (ctx->parser, girname);
2351 if (girpath == NULL)
2355 G_MARKUP_ERROR_INVALID_CONTENT,
2356 "Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir",
2363 g_debug ("Parsing include %s", girpath);
2365 if (!g_file_get_contents (girpath, &buffer, &length, error))
2372 modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error);
2373 success = error != NULL;
2375 ctx->include_modules = g_list_concat (ctx->include_modules,
2383 extern GLogLevelFlags logged_levels;
2386 start_element_handler (GMarkupParseContext *context,
2387 const gchar *element_name,
2388 const gchar **attribute_names,
2389 const gchar **attribute_values,
2393 ParseContext *ctx = user_data;
2394 gint line_number, char_number;
2396 if (logged_levels & G_LOG_LEVEL_DEBUG)
2398 GString *tags = g_string_new ("");
2400 for (i = 0; attribute_names[i]; i++)
2401 g_string_append_printf (tags, "%s=\"%s\" ",
2403 attribute_values[i]);
2407 g_string_insert_c (tags, 0, ' ');
2408 g_string_truncate (tags, tags->len - 1);
2410 g_debug ("<%s%s>", element_name, tags->str);
2411 g_string_free (tags, TRUE);
2414 switch (element_name[0])
2417 if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0)
2419 state_switch (ctx, STATE_ALIAS);
2422 if (start_type (context, element_name,
2423 attribute_names, attribute_values,
2426 else if (start_attribute (context, element_name,
2427 attribute_names, attribute_values,
2432 if (start_enum (context, element_name,
2433 attribute_names, attribute_values,
2438 if (start_function (context, element_name,
2439 attribute_names, attribute_values,
2442 else if (start_constant (context, element_name,
2443 attribute_names, attribute_values,
2446 else if (start_class (context, element_name,
2447 attribute_names, attribute_values,
2453 if (start_discriminator (context, element_name,
2454 attribute_names, attribute_values,
2460 if (start_enum (context, element_name,
2461 attribute_names, attribute_values,
2464 else if (start_errordomain (context, element_name,
2465 attribute_names, attribute_values,
2471 if (start_function (context, element_name,
2472 attribute_names, attribute_values,
2475 else if (start_field (context, element_name,
2476 attribute_names, attribute_values,
2482 if (start_glib_boxed (context, element_name,
2483 attribute_names, attribute_values,
2486 else if (start_glib_signal (context, element_name,
2487 attribute_names, attribute_values,
2493 if (strcmp (element_name, "include") == 0 &&
2494 ctx->state == STATE_REPOSITORY)
2497 const gchar *version;
2499 name = find_attribute ("name", attribute_names, attribute_values);
2500 version = find_attribute ("version", attribute_names, attribute_values);
2504 MISSING_ATTRIBUTE (context, error, element_name, "name");
2507 if (version == NULL)
2509 MISSING_ATTRIBUTE (context, error, element_name, "version");
2513 if (!parse_include (context, ctx, name, version, error))
2516 ctx->dependencies = g_list_prepend (ctx->dependencies,
2517 g_strdup_printf ("%s-%s", name, version));
2520 state_switch (ctx, STATE_INCLUDE);
2523 if (start_interface (context, element_name,
2524 attribute_names, attribute_values,
2527 else if (start_implements (context, element_name,
2528 attribute_names, attribute_values,
2534 if (start_function (context, element_name,
2535 attribute_names, attribute_values,
2538 else if (start_member (context, element_name,
2539 attribute_names, attribute_values,
2545 if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2547 const gchar *name, *version, *shared_library, *cprefix;
2549 if (ctx->current_module != NULL)
2553 G_MARKUP_ERROR_INVALID_CONTENT,
2554 "Only one <namespace/> element is currently allowed per <repository/>");
2558 name = find_attribute ("name", attribute_names, attribute_values);
2559 version = find_attribute ("version", attribute_names, attribute_values);
2560 shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2561 cprefix = find_attribute ("c:prefix", attribute_names, attribute_values);
2564 MISSING_ATTRIBUTE (context, error, element_name, "name");
2565 else if (version == NULL)
2566 MISSING_ATTRIBUTE (context, error, element_name, "version");
2571 if (strcmp (name, ctx->namespace) != 0)
2574 G_MARKUP_ERROR_INVALID_CONTENT,
2575 "<namespace/> name element '%s' doesn't match file name '%s'",
2576 name, ctx->namespace);
2578 ctx->current_module = g_ir_module_new (name, version, shared_library, cprefix);
2580 ctx->current_module->aliases = ctx->aliases;
2581 ctx->aliases = NULL;
2582 ctx->current_module->disguised_structures = ctx->disguised_structures;
2583 ctx->disguised_structures = NULL;
2585 for (l = ctx->include_modules; l; l = l->next)
2586 g_ir_module_add_include_module (ctx->current_module, l->data);
2588 g_list_free (ctx->include_modules);
2589 ctx->include_modules = NULL;
2591 ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2592 ctx->current_module->dependencies = ctx->dependencies;
2594 state_switch (ctx, STATE_NAMESPACE);
2601 if (start_property (context, element_name,
2602 attribute_names, attribute_values,
2605 else if (strcmp (element_name, "parameters") == 0 &&
2606 ctx->state == STATE_FUNCTION)
2608 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2612 else if (start_parameter (context, element_name,
2613 attribute_names, attribute_values,
2616 else if (strcmp (element_name, "prerequisite") == 0 &&
2617 ctx->state == STATE_INTERFACE)
2621 name = find_attribute ("name", attribute_names, attribute_values);
2623 state_switch (ctx, STATE_PREREQUISITE);
2626 MISSING_ATTRIBUTE (context, error, element_name, "name");
2629 GIrNodeInterface *iface;
2631 iface = (GIrNodeInterface *)CURRENT_NODE(ctx);
2632 iface->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
2636 else if (strcmp (element_name, "package") == 0 &&
2637 ctx->state == STATE_REPOSITORY)
2639 state_switch (ctx, STATE_PACKAGE);
2645 if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
2647 const gchar *version;
2649 version = find_attribute ("version", attribute_names, attribute_values);
2651 if (version == NULL)
2652 MISSING_ATTRIBUTE (context, error, element_name, "version");
2653 else if (strcmp (version, "1.0") != 0)
2656 G_MARKUP_ERROR_INVALID_CONTENT,
2657 "Unsupported version '%s'",
2660 state_switch (ctx, STATE_REPOSITORY);
2664 else if (start_return_value (context, element_name,
2665 attribute_names, attribute_values,
2668 else if (start_struct (context, element_name,
2669 attribute_names, attribute_values,
2675 if (start_union (context, element_name,
2676 attribute_names, attribute_values,
2682 if (start_type (context, element_name,
2683 attribute_names, attribute_values,
2689 if (start_vfunc (context, element_name,
2690 attribute_names, attribute_values,
2693 if (start_type (context, element_name,
2694 attribute_names, attribute_values,
2700 if (ctx->state != STATE_UNKNOWN)
2702 state_switch (ctx, STATE_UNKNOWN);
2703 ctx->unknown_depth = 1;
2707 ctx->unknown_depth += 1;
2713 g_markup_parse_context_get_position (context, &line_number, &char_number);
2715 fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message);
2716 backtrace_stderr ();
2721 require_one_of_end_elements (GMarkupParseContext *context,
2723 const char *actual_name,
2728 int line_number, char_number;
2729 const char *expected;
2730 gboolean matched = FALSE;
2732 va_start (args, error);
2734 while ((expected = va_arg (args, const char*)) != NULL)
2736 if (strcmp (expected, actual_name) == 0)
2748 g_markup_parse_context_get_position (context, &line_number, &char_number);
2751 G_MARKUP_ERROR_INVALID_CONTENT,
2752 "Unexpected end tag '%s' on line %d char %d; current state=%d",
2754 line_number, char_number, ctx->state);
2760 state_switch_end_struct_or_union (GMarkupParseContext *context,
2762 const gchar *element_name,
2766 if (ctx->node_stack == NULL)
2768 state_switch (ctx, STATE_NAMESPACE);
2772 if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2773 state_switch (ctx, STATE_STRUCT);
2774 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2775 state_switch (ctx, STATE_UNION);
2776 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2777 state_switch (ctx, STATE_CLASS);
2780 int line_number, char_number;
2781 g_markup_parse_context_get_position (context, &line_number, &char_number);
2784 G_MARKUP_ERROR_INVALID_CONTENT,
2785 "Unexpected end tag '%s' on line %d char %d",
2787 line_number, char_number);
2795 require_end_element (GMarkupParseContext *context,
2797 const char *expected_name,
2798 const char *actual_name,
2801 return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
2805 end_element_handler (GMarkupParseContext *context,
2806 const gchar *element_name,
2810 ParseContext *ctx = user_data;
2812 g_debug ("</%s>", element_name);
2818 /* no need to GError here, GMarkup already catches this */
2821 case STATE_REPOSITORY:
2822 state_switch (ctx, STATE_END);
2826 if (require_end_element (context, ctx, "include", element_name, error))
2828 state_switch (ctx, STATE_REPOSITORY);
2833 if (require_end_element (context, ctx, "package", element_name, error))
2835 state_switch (ctx, STATE_REPOSITORY);
2839 case STATE_NAMESPACE:
2840 if (require_end_element (context, ctx, "namespace", element_name, error))
2842 ctx->current_module = NULL;
2843 state_switch (ctx, STATE_REPOSITORY);
2848 if (require_end_element (context, ctx, "alias", element_name, error))
2850 state_switch (ctx, STATE_NAMESPACE);
2854 case STATE_FUNCTION_RETURN:
2855 if (strcmp ("type", element_name) == 0)
2857 if (require_end_element (context, ctx, "return-value", element_name, error))
2859 state_switch (ctx, STATE_FUNCTION);
2863 case STATE_FUNCTION_PARAMETERS:
2864 if (require_end_element (context, ctx, "parameters", element_name, error))
2866 state_switch (ctx, STATE_FUNCTION);
2870 case STATE_FUNCTION_PARAMETER:
2871 if (strcmp ("type", element_name) == 0)
2873 if (require_end_element (context, ctx, "parameter", element_name, error))
2875 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2879 case STATE_FUNCTION:
2882 if (ctx->node_stack == NULL)
2884 state_switch (ctx, STATE_NAMESPACE);
2888 if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
2889 state_switch (ctx, STATE_INTERFACE);
2890 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2891 state_switch (ctx, STATE_CLASS);
2892 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_BOXED)
2893 state_switch (ctx, STATE_BOXED);
2894 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2895 state_switch (ctx, STATE_STRUCT);
2896 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2897 state_switch (ctx, STATE_UNION);
2900 int line_number, char_number;
2901 g_markup_parse_context_get_position (context, &line_number, &char_number);
2904 G_MARKUP_ERROR_INVALID_CONTENT,
2905 "Unexpected end tag '%s' on line %d char %d",
2907 line_number, char_number);
2913 case STATE_CLASS_FIELD:
2914 if (strcmp ("type", element_name) == 0)
2916 if (require_end_element (context, ctx, "field", element_name, error))
2918 state_switch (ctx, STATE_CLASS);
2922 case STATE_CLASS_PROPERTY:
2923 if (strcmp ("type", element_name) == 0)
2925 if (require_end_element (context, ctx, "property", element_name, error))
2927 state_switch (ctx, STATE_CLASS);
2932 if (require_end_element (context, ctx, "class", element_name, error))
2935 state_switch (ctx, STATE_NAMESPACE);
2939 case STATE_ERRORDOMAIN:
2940 if (require_end_element (context, ctx, "errordomain", element_name, error))
2943 state_switch (ctx, STATE_NAMESPACE);
2947 case STATE_INTERFACE_PROPERTY:
2948 if (strcmp ("type", element_name) == 0)
2950 if (require_end_element (context, ctx, "property", element_name, error))
2952 state_switch (ctx, STATE_INTERFACE);
2956 case STATE_INTERFACE_FIELD:
2957 if (strcmp ("type", element_name) == 0)
2959 if (require_end_element (context, ctx, "field", element_name, error))
2961 state_switch (ctx, STATE_INTERFACE);
2965 case STATE_INTERFACE:
2966 if (require_end_element (context, ctx, "interface", element_name, error))
2969 state_switch (ctx, STATE_NAMESPACE);
2974 if (strcmp ("member", element_name) == 0)
2976 else if (require_one_of_end_elements (context, ctx,
2977 element_name, error, "enumeration",
2981 state_switch (ctx, STATE_NAMESPACE);
2986 if (require_end_element (context, ctx, "glib:boxed", element_name, error))
2989 state_switch (ctx, STATE_NAMESPACE);
2993 case STATE_BOXED_FIELD:
2994 if (strcmp ("type", element_name) == 0)
2996 if (require_end_element (context, ctx, "field", element_name, error))
2998 state_switch (ctx, STATE_BOXED);
3002 case STATE_STRUCT_FIELD:
3003 if (strcmp ("type", element_name) == 0)
3005 if (require_end_element (context, ctx, "field", element_name, error))
3007 state_switch (ctx, STATE_STRUCT);
3012 if (require_end_element (context, ctx, "record", element_name, error))
3014 state_switch_end_struct_or_union (context, ctx, element_name, error);
3018 case STATE_UNION_FIELD:
3019 if (strcmp ("type", element_name) == 0)
3021 if (require_end_element (context, ctx, "field", element_name, error))
3023 state_switch (ctx, STATE_UNION);
3028 if (require_end_element (context, ctx, "union", element_name, error))
3030 state_switch_end_struct_or_union (context, ctx, element_name, error);
3033 case STATE_IMPLEMENTS:
3034 if (strcmp ("interface", element_name) == 0)
3036 if (require_end_element (context, ctx, "implements", element_name, error))
3037 state_switch (ctx, STATE_CLASS);
3039 case STATE_PREREQUISITE:
3040 if (require_end_element (context, ctx, "prerequisite", element_name, error))
3041 state_switch (ctx, STATE_INTERFACE);
3043 case STATE_NAMESPACE_CONSTANT:
3044 case STATE_CLASS_CONSTANT:
3045 case STATE_INTERFACE_CONSTANT:
3046 if (strcmp ("type", element_name) == 0)
3048 if (require_end_element (context, ctx, "constant", element_name, error))
3052 case STATE_NAMESPACE_CONSTANT:
3054 state_switch (ctx, STATE_NAMESPACE);
3056 case STATE_CLASS_CONSTANT:
3057 state_switch (ctx, STATE_CLASS);
3059 case STATE_INTERFACE_CONSTANT:
3060 state_switch (ctx, STATE_INTERFACE);
3063 g_assert_not_reached ();
3069 if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
3070 (strcmp ("varargs", element_name) == 0))
3075 case STATE_ATTRIBUTE:
3076 if (strcmp ("attribute", element_name) == 0)
3078 state_switch (ctx, ctx->prev_state);
3083 ctx->unknown_depth -= 1;
3084 if (ctx->unknown_depth == 0)
3085 state_switch (ctx, ctx->prev_state);
3088 g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
3093 text_handler (GMarkupParseContext *context,
3099 /* FIXME warn about non-whitespace text */
3103 cleanup (GMarkupParseContext *context,
3107 ParseContext *ctx = user_data;
3110 for (m = ctx->modules; m; m = m->next)
3111 g_ir_module_free (m->data);
3112 g_list_free (ctx->modules);
3113 ctx->modules = NULL;
3115 ctx->current_module = NULL;
3119 post_filter_toplevel_varargs_functions (GList *list,
3120 GList **varargs_callbacks_out)
3123 GList *varargs_callbacks = *varargs_callbacks_out;
3129 GIrNode *node = iter->data;
3133 if (node->type == G_IR_NODE_FUNCTION)
3135 if (((GIrNodeFunction*)node)->is_varargs)
3137 list = g_list_delete_link (list, link);
3140 if (node->type == G_IR_NODE_CALLBACK)
3142 if (((GIrNodeFunction*)node)->is_varargs)
3144 varargs_callbacks = g_list_append (varargs_callbacks,
3146 list = g_list_delete_link (list, link);
3151 *varargs_callbacks_out = varargs_callbacks;
3157 post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out)
3160 GList *varargs_callbacks;
3162 list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out);
3164 varargs_callbacks = *varargs_callbacks_out;
3170 GIrNode *node = iter->data;
3174 if (node->type == G_IR_NODE_FUNCTION)
3177 gboolean function_done = FALSE;
3179 for (param = ((GIrNodeFunction *)node)->parameters;
3181 param = param->next)
3183 GIrNodeParam *node = (GIrNodeParam *)param->data;
3188 if (node->type->is_interface)
3191 for (callback = varargs_callbacks;
3193 callback = callback->next)
3195 if (!strcmp (node->type->interface,
3196 ((GIrNode *)varargs_callbacks->data)->name))
3198 list = g_list_delete_link (list, link);
3199 function_done = TRUE;
3208 *varargs_callbacks_out = varargs_callbacks;
3214 post_filter (GIrModule *module)
3217 GList *varargs_callbacks = NULL;
3219 module->entries = post_filter_varargs_functions (module->entries,
3220 &varargs_callbacks);
3221 iter = module->entries;
3224 GIrNode *node = iter->data;
3228 if (node->type == G_IR_NODE_OBJECT ||
3229 node->type == G_IR_NODE_INTERFACE)
3231 GIrNodeInterface *iface = (GIrNodeInterface*)node;
3232 iface->members = post_filter_varargs_functions (iface->members,
3233 &varargs_callbacks);
3235 else if (node->type == G_IR_NODE_BOXED)
3237 GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
3238 boxed->members = post_filter_varargs_functions (boxed->members,
3239 &varargs_callbacks);
3241 else if (node->type == G_IR_NODE_STRUCT)
3243 GIrNodeStruct *iface = (GIrNodeStruct*)node;
3244 iface->members = post_filter_varargs_functions (iface->members,
3245 &varargs_callbacks);
3247 else if (node->type == G_IR_NODE_UNION)
3249 GIrNodeUnion *iface = (GIrNodeUnion*)node;
3250 iface->members = post_filter_varargs_functions (iface->members,
3251 &varargs_callbacks);
3254 g_list_free (varargs_callbacks);
3258 * g_ir_parser_parse_string:
3259 * @parser: a #GIrParser
3260 * @namespace: the namespace of the string
3261 * @buffer: the data containing the XML
3262 * @length: length of the data
3263 * @error: return location for a #GError, or %NULL
3265 * Parse a string that holds a complete GIR XML file, and return a list of a
3266 * a #GirModule for each <namespace/> element within the file.
3268 * Returns: a newly allocated list of #GIrModule. The modules themselves
3269 * are owned by the #GIrParser and will be freed along with the parser.
3272 g_ir_parser_parse_string (GIrParser *parser,
3273 const gchar *namespace,
3274 const gchar *buffer,
3278 ParseContext ctx = { 0 };
3279 GMarkupParseContext *context;
3281 ctx.parser = parser;
3282 ctx.state = STATE_START;
3283 ctx.namespace = namespace;
3284 ctx.include_modules = NULL;
3285 ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
3286 ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
3288 ctx.dependencies = NULL;
3289 ctx.current_module = NULL;
3291 context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
3293 if (!g_markup_parse_context_parse (context, buffer, length, error))
3296 if (!g_markup_parse_context_end_parse (context, error))
3299 g_markup_parse_context_free (context);
3301 context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL);
3302 if (!g_markup_parse_context_parse (context, buffer, length, error))
3305 if (!g_markup_parse_context_end_parse (context, error))
3308 parser->parsed_modules = g_list_concat (g_list_copy (ctx.modules),
3309 parser->parsed_modules);
3313 if (ctx.modules == NULL)
3315 /* An error occurred before we created a module, so we haven't
3316 * transferred ownership of these hash tables to the module.
3318 if (ctx.aliases != NULL)
3319 g_hash_table_destroy (ctx.aliases);
3320 if (ctx.disguised_structures != NULL)
3321 g_hash_table_destroy (ctx.disguised_structures);
3322 g_list_free (ctx.include_modules);
3325 g_markup_parse_context_free (context);
3331 * g_ir_parser_parse_file:
3332 * @parser: a #GIrParser
3333 * @filename: filename to parse
3334 * @error: return location for a #GError, or %NULL
3336 * Parse GIR XML file, and return a list of a a #GirModule for each
3337 * <namespace/> element within the file.
3339 * Returns: a newly allocated list of #GIrModule. The modules themselves
3340 * are owned by the #GIrParser and will be freed along with the parser.
3343 g_ir_parser_parse_file (GIrParser *parser,
3344 const gchar *filename,
3355 if (!g_str_has_suffix (filename, ".gir"))
3359 G_MARKUP_ERROR_INVALID_CONTENT,
3360 "Expected filename to end with '.gir'");
3364 g_debug ("[parsing] filename %s", filename);
3366 slash = g_strrstr (filename, "/");
3368 namespace = g_strdup (filename);
3370 namespace = g_strdup (slash+1);
3371 namespace[strlen(namespace)-4] = '\0';
3373 /* Remove version */
3374 dash = strstr (namespace, "-");
3378 if (!g_file_get_contents (filename, &buffer, &length, error))
3381 modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error);
3383 for (iter = modules; iter; iter = iter->next)
3385 post_filter ((GIrModule*)iter->data);