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"
32 #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
33 # include <execinfo.h>
39 GList *parsed_modules; /* All previously parsed modules */
49 STATE_NAMESPACE, /* 5 */
53 STATE_FUNCTION_RETURN,
54 STATE_FUNCTION_PARAMETERS, /* 10 */
55 STATE_FUNCTION_PARAMETER,
59 STATE_INTERFACE, /* 15 */
60 STATE_INTERFACE_PROPERTY,
61 STATE_INTERFACE_FIELD,
71 STATE_NAMESPACE_CONSTANT,
73 STATE_INTERFACE_CONSTANT,
80 typedef struct _ParseContext ParseContext;
87 ParseState prev_state;
90 GList *include_modules;
93 GHashTable *disguised_structures;
95 const char *namespace;
97 GIrModule *current_module;
99 GIrNode *current_typed;
102 GList *type_parameters;
104 gboolean in_embedded_type;
106 #define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
108 static void start_element_handler (GMarkupParseContext *context,
109 const gchar *element_name,
110 const gchar **attribute_names,
111 const gchar **attribute_values,
114 static void end_element_handler (GMarkupParseContext *context,
115 const gchar *element_name,
118 static void text_handler (GMarkupParseContext *context,
123 static void cleanup (GMarkupParseContext *context,
127 static GMarkupParser markup_parser =
129 start_element_handler,
137 start_alias (GMarkupParseContext *context,
138 const gchar *element_name,
139 const gchar **attribute_names,
140 const gchar **attribute_values,
144 static const gchar *find_attribute (const gchar *name,
145 const gchar **attribute_names,
146 const gchar **attribute_values);
150 g_ir_parser_new (void)
152 GIrParser *parser = g_slice_new0 (GIrParser);
158 g_ir_parser_free (GIrParser *parser)
162 if (parser->includes)
163 g_strfreev (parser->includes);
165 for (l = parser->parsed_modules; l; l = l->next)
166 g_ir_module_free (l->data);
168 g_slice_free (GIrParser, parser);
172 g_ir_parser_set_includes (GIrParser *parser,
173 const gchar *const *includes)
175 if (parser->includes)
176 g_strfreev (parser->includes);
178 parser->includes = g_strdupv ((char **)includes);
182 firstpass_start_element_handler (GMarkupParseContext *context,
183 const gchar *element_name,
184 const gchar **attribute_names,
185 const gchar **attribute_values,
189 ParseContext *ctx = user_data;
191 if (strcmp (element_name, "alias") == 0)
193 start_alias (context, element_name, attribute_names, attribute_values,
196 else if (strcmp (element_name, "record") == 0)
199 const gchar *disguised;
201 name = find_attribute ("name", attribute_names, attribute_values);
202 disguised = find_attribute ("disguised", attribute_names, attribute_values);
204 if (disguised && strcmp (disguised, "1") == 0)
208 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
209 g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
215 firstpass_end_element_handler (GMarkupParseContext *context,
216 const gchar *element_name,
222 static GMarkupParser firstpass_parser =
224 firstpass_start_element_handler,
225 firstpass_end_element_handler,
232 locate_gir (GIrParser *parser,
235 const gchar *const *datadirs;
236 const gchar *const *dir;
239 datadirs = g_get_system_data_dirs ();
241 if (parser->includes != NULL)
243 for (dir = (const gchar *const *)parser->includes; *dir; dir++)
245 path = g_build_filename (*dir, girname, NULL);
246 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
252 for (dir = datadirs; *dir; dir++)
254 path = g_build_filename (*dir, GIR_SUFFIX, girname, NULL);
255 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
261 path = g_build_filename (GIR_DIR, girname, NULL);
262 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
268 #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \
270 int line_number, char_number; \
271 g_markup_parse_context_get_position (context, &line_number, &char_number); \
272 g_set_error (error, \
274 G_MARKUP_ERROR_INVALID_CONTENT, \
275 "Line %d, character %d: The attribute '%s' on the element '%s' must be specified", \
276 line_number, char_number, attribute, element); \
280 backtrace_stderr (void)
282 #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
287 size = backtrace (array, 50);
288 strings = (char**) backtrace_symbols (array, size);
290 fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size);
292 for (i = 0; i < size; i++)
293 fprintf (stderr, "%s\n", strings[i]);
295 fprintf (stderr, "--- END BACKTRACE ---\n");
303 find_attribute (const gchar *name,
304 const gchar **attribute_names,
305 const gchar **attribute_values)
309 for (i = 0; attribute_names[i] != NULL; i++)
310 if (strcmp (attribute_names[i], name) == 0)
311 return attribute_values[i];
317 state_switch (ParseContext *ctx, ParseState newstate)
319 g_debug ("State: %d", newstate);
320 ctx->prev_state = ctx->state;
321 ctx->state = newstate;
325 pop_node (ParseContext *ctx)
327 g_assert (ctx->node_stack != 0);
329 GSList *top = ctx->node_stack;
330 GIrNode *node = top->data;
332 g_debug ("popping node %d %s", node->type, node->name);
333 ctx->node_stack = top->next;
334 g_slist_free_1 (top);
339 push_node (ParseContext *ctx, GIrNode *node)
341 g_debug ("pushing node %d %s", node->type, node->name);
342 ctx->node_stack = g_slist_prepend (ctx->node_stack, node);
345 static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
346 gboolean in_gobject);
354 static BasicTypeInfo basic_types[] = {
355 { "none", GI_TYPE_TAG_VOID, 0 },
356 { "any", GI_TYPE_TAG_VOID, 1 },
358 { "bool", GI_TYPE_TAG_BOOLEAN, 0 },
359 { "char", GI_TYPE_TAG_INT8, 0 },
360 { "int8", GI_TYPE_TAG_INT8, 0 },
361 { "uint8", GI_TYPE_TAG_UINT8, 0 },
362 { "int16", GI_TYPE_TAG_INT16, 0 },
363 { "uint16", GI_TYPE_TAG_UINT16, 0 },
364 { "int32", GI_TYPE_TAG_INT32, 0 },
365 { "uint32", GI_TYPE_TAG_UINT32, 0 },
366 { "int64", GI_TYPE_TAG_INT64, 0 },
367 { "uint64", GI_TYPE_TAG_UINT64, 0 },
368 { "short", GI_TYPE_TAG_SHORT, 0 },
369 { "ushort", GI_TYPE_TAG_USHORT, 0 },
370 { "int", GI_TYPE_TAG_INT, 0 },
371 { "uint", GI_TYPE_TAG_UINT, 0 },
372 { "long", GI_TYPE_TAG_LONG, 0 },
373 { "ulong", GI_TYPE_TAG_ULONG, 0 },
374 { "ssize_t", GI_TYPE_TAG_SSIZE, 0 },
375 { "ssize", GI_TYPE_TAG_SSIZE, 0 },
376 { "size_t", GI_TYPE_TAG_SIZE, 0 },
377 { "size", GI_TYPE_TAG_SIZE, 0 },
378 { "float", GI_TYPE_TAG_FLOAT, 0 },
379 { "double", GI_TYPE_TAG_DOUBLE, 0 },
380 { "time_t", GI_TYPE_TAG_TIME_T, 0 },
381 { "GType", GI_TYPE_TAG_GTYPE, 0 },
382 { "utf8", GI_TYPE_TAG_UTF8, 1 },
383 { "filename", GI_TYPE_TAG_FILENAME,1 },
386 static const BasicTypeInfo *
387 parse_basic (const char *str)
390 gint n_basic = G_N_ELEMENTS (basic_types);
392 for (i = 0; i < n_basic; i++)
394 if (g_str_has_prefix (str, basic_types[i].str))
395 return &(basic_types[i]);
401 parse_type_internal (const gchar *str, char **next, gboolean in_glib,
404 const BasicTypeInfo *basic;
406 char *temporary_type = NULL;
408 type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
410 type->unparsed = g_strdup (str);
412 /* See comment below on GLib.List handling */
413 if (in_gobject && strcmp (str, "Type") == 0)
415 temporary_type = g_strdup ("GLib.Type");
416 str = temporary_type;
419 basic = parse_basic (str);
422 type->is_basic = TRUE;
423 type->tag = basic->tag;
424 type->is_pointer = basic->pointer;
426 str += strlen(basic->str);
430 /* If we're inside GLib, handle "List" etc. by prefixing with
431 * "GLib." so the parsing code below doesn't have to get more
434 if (g_str_has_prefix (str, "List<") ||
435 strcmp (str, "List") == 0)
437 temporary_type = g_strdup_printf ("GLib.List%s", str + 4);
438 str = temporary_type;
440 else if (g_str_has_prefix (str, "SList<") ||
441 strcmp (str, "SList") == 0)
443 temporary_type = g_strdup_printf ("GLib.SList%s", str + 5);
444 str = temporary_type;
446 else if (g_str_has_prefix (str, "HashTable<") ||
447 strcmp (str, "HashTable") == 0)
449 temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9);
450 str = temporary_type;
452 else if (g_str_has_prefix (str, "Error<") ||
453 strcmp (str, "Error") == 0)
455 temporary_type = g_strdup_printf ("GLib.Error%s", str + 5);
456 str = temporary_type;
461 /* found a basic type */;
462 else if (g_str_has_prefix (str, "GLib.List") ||
463 g_str_has_prefix (str, "GLib.SList"))
465 str += strlen ("GLib.");
466 if (g_str_has_prefix (str, "List"))
468 type->tag = GI_TYPE_TAG_GLIST;
469 type->is_glist = TRUE;
470 type->is_pointer = TRUE;
471 str += strlen ("List");
475 type->tag = GI_TYPE_TAG_GSLIST;
476 type->is_gslist = TRUE;
477 type->is_pointer = TRUE;
478 str += strlen ("SList");
481 else if (g_str_has_prefix (str, "GLib.HashTable"))
483 str += strlen ("GLib.");
485 type->tag = GI_TYPE_TAG_GHASH;
486 type->is_ghashtable = TRUE;
487 type->is_pointer = TRUE;
488 str += strlen ("HashTable");
490 else if (g_str_has_prefix (str, "GLib.Error"))
492 str += strlen ("GLib.");
494 type->tag = GI_TYPE_TAG_ERROR;
495 type->is_error = TRUE;
496 type->is_pointer = TRUE;
497 str += strlen ("Error");
504 end = strchr (str, '>');
505 tmp = g_strndup (str, end - str);
506 type->errors = g_strsplit (tmp, ",", 0);
514 type->tag = GI_TYPE_TAG_INTERFACE;
515 type->is_interface = TRUE;
516 const char *start = str;
518 /* must be an interface type */
519 while (g_ascii_isalnum (*str) ||
526 type->interface = g_strndup (start, str - start);
531 g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR);
532 g_free (temporary_type);
536 g_ir_node_free ((GIrNode *)type);
537 g_free (temporary_type);
542 resolve_aliases (ParseContext *ctx, const gchar *type)
546 GSList *seen_values = NULL;
550 if (strchr (type, '.') == NULL)
552 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
561 seen_values = g_slist_prepend (seen_values, (char*)lookup);
562 while (g_hash_table_lookup_extended (ctx->current_module->aliases, lookup, &orig, &value))
564 g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
566 if (g_slist_find_custom (seen_values, lookup,
567 (GCompareFunc)strcmp) != NULL)
569 seen_values = g_slist_prepend (seen_values, (gchar*)lookup);
571 g_slist_free (seen_values);
573 if (lookup == prefixed)
582 is_disguised_structure (ParseContext *ctx, const gchar *type)
588 if (strchr (type, '.') == NULL)
590 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
599 result = g_hash_table_lookup (ctx->current_module->disguised_structures,
608 parse_type (ParseContext *ctx, const gchar *type)
611 const BasicTypeInfo *basic;
612 gboolean in_glib, in_gobject;
614 in_glib = strcmp (ctx->namespace, "GLib") == 0;
615 in_gobject = strcmp (ctx->namespace, "GObject") == 0;
617 /* Do not search aliases for basic types */
618 basic = parse_basic (type);
620 type = resolve_aliases (ctx, type);
622 node = parse_type_internal (type, NULL, in_glib, in_gobject);
624 g_debug ("Parsed type: %s => %d", type, node->tag);
626 g_critical ("Failed to parse type: '%s'", type);
632 start_glib_boxed (GMarkupParseContext *context,
633 const gchar *element_name,
634 const gchar **attribute_names,
635 const gchar **attribute_values,
640 const gchar *typename;
641 const gchar *typeinit;
642 const gchar *deprecated;
645 if (!(strcmp (element_name, "glib:boxed") == 0 &&
646 ctx->state == STATE_NAMESPACE))
649 name = find_attribute ("glib:name", attribute_names, attribute_values);
650 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
651 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
652 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
656 MISSING_ATTRIBUTE (context, error, element_name, "glib:name");
659 else if (typename == NULL)
661 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
664 else if (typeinit == NULL)
666 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
670 boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED);
672 ((GIrNode *)boxed)->name = g_strdup (name);
673 boxed->gtype_name = g_strdup (typename);
674 boxed->gtype_init = g_strdup (typeinit);
676 boxed->deprecated = TRUE;
678 boxed->deprecated = FALSE;
680 push_node (ctx, (GIrNode *)boxed);
681 ctx->current_module->entries =
682 g_list_append (ctx->current_module->entries, boxed);
684 state_switch (ctx, STATE_BOXED);
690 start_function (GMarkupParseContext *context,
691 const gchar *element_name,
692 const gchar **attribute_names,
693 const gchar **attribute_values,
699 const gchar *deprecated;
701 GIrNodeFunction *function;
702 gboolean found = FALSE;
706 case STATE_NAMESPACE:
707 found = (strcmp (element_name, "function") == 0 ||
708 strcmp (element_name, "callback") == 0);
711 found = strcmp (element_name, "function") == 0;
716 found = (found || strcmp (element_name, "constructor") == 0);
718 case STATE_INTERFACE:
720 strcmp (element_name, "method") == 0 ||
721 strcmp (element_name, "callback") == 0);
723 case STATE_STRUCT_FIELD:
724 ctx->in_embedded_type = TRUE;
725 found = (found || strcmp (element_name, "callback") == 0);
734 name = find_attribute ("name", attribute_names, attribute_values);
735 symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
736 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
737 throws = find_attribute ("throws", attribute_names, attribute_values);
741 MISSING_ATTRIBUTE (context, error, element_name, "name");
744 else if (strcmp (element_name, "callback") != 0 && symbol == NULL)
746 MISSING_ATTRIBUTE (context, error, element_name, "c:identifier");
750 function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION);
752 ((GIrNode *)function)->name = g_strdup (name);
753 function->symbol = g_strdup (symbol);
754 function->parameters = NULL;
756 function->deprecated = TRUE;
758 function->deprecated = FALSE;
760 if (strcmp (element_name, "method") == 0 ||
761 strcmp (element_name, "constructor") == 0)
763 function->is_method = TRUE;
765 if (strcmp (element_name, "constructor") == 0)
766 function->is_constructor = TRUE;
768 function->is_constructor = FALSE;
772 function->is_method = FALSE;
773 function->is_setter = FALSE;
774 function->is_getter = FALSE;
775 function->is_constructor = FALSE;
776 if (strcmp (element_name, "callback") == 0)
777 ((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
780 if (throws && strcmp (throws, "1") == 0)
781 function->throws = TRUE;
783 function->throws = FALSE;
785 if (ctx->node_stack == NULL)
787 ctx->current_module->entries =
788 g_list_append (ctx->current_module->entries, function);
790 else if (ctx->current_typed)
794 field = (GIrNodeField *)ctx->current_typed;
795 field->callback = function;
798 switch (CURRENT_NODE (ctx)->type)
800 case G_IR_NODE_INTERFACE:
801 case G_IR_NODE_OBJECT:
803 GIrNodeInterface *iface;
805 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
806 iface->members = g_list_append (iface->members, function);
809 case G_IR_NODE_BOXED:
813 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
814 boxed->members = g_list_append (boxed->members, function);
817 case G_IR_NODE_STRUCT:
819 GIrNodeStruct *struct_;
821 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
822 struct_->members = g_list_append (struct_->members, function); }
824 case G_IR_NODE_UNION:
826 GIrNodeUnion *union_;
828 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
829 union_->members = g_list_append (union_->members, function);
833 g_assert_not_reached ();
836 push_node(ctx, (GIrNode *)function);
837 state_switch (ctx, STATE_FUNCTION);
843 parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *name)
845 if (transfer == NULL)
848 g_warning ("required attribute 'transfer-ownership' missing");
850 g_warning ("required attribute 'transfer-ownership' for function '%s'", name);
852 else if (strcmp (transfer, "none") == 0)
854 param->transfer = FALSE;
855 param->shallow_transfer = FALSE;
857 else if (strcmp (transfer, "container") == 0)
859 param->transfer = FALSE;
860 param->shallow_transfer = TRUE;
862 else if (strcmp (transfer, "full") == 0)
864 param->transfer = TRUE;
865 param->shallow_transfer = FALSE;
869 g_warning ("Unknown transfer-ownership value: %s", transfer);
874 start_parameter (GMarkupParseContext *context,
875 const gchar *element_name,
876 const gchar **attribute_names,
877 const gchar **attribute_values,
882 const gchar *direction;
885 const gchar *optional;
886 const gchar *allow_none;
887 const gchar *transfer;
889 const gchar *closure;
890 const gchar *destroy;
893 if (!(strcmp (element_name, "parameter") == 0 &&
894 ctx->state == STATE_FUNCTION_PARAMETERS))
897 name = find_attribute ("name", attribute_names, attribute_values);
898 direction = find_attribute ("direction", attribute_names, attribute_values);
899 retval = find_attribute ("retval", attribute_names, attribute_values);
900 dipper = find_attribute ("dipper", attribute_names, attribute_values);
901 optional = find_attribute ("optional", attribute_names, attribute_values);
902 allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
903 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
904 scope = find_attribute ("scope", attribute_names, attribute_values);
905 closure = find_attribute ("closure", attribute_names, attribute_values);
906 destroy = find_attribute ("destroy", attribute_names, attribute_values);
911 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
913 ctx->current_typed = (GIrNode*) param;
914 ctx->current_typed->name = g_strdup (name);
916 state_switch (ctx, STATE_FUNCTION_PARAMETER);
918 if (direction && strcmp (direction, "out") == 0)
923 else if (direction && strcmp (direction, "inout") == 0)
934 if (retval && strcmp (retval, "1") == 0)
935 param->retval = TRUE;
937 param->retval = FALSE;
939 if (dipper && strcmp (dipper, "1") == 0)
940 param->dipper = TRUE;
942 param->dipper = FALSE;
944 if (optional && strcmp (optional, "1") == 0)
945 param->optional = TRUE;
947 param->optional = FALSE;
949 if (allow_none && strcmp (allow_none, "1") == 0)
950 param->allow_none = TRUE;
952 param->allow_none = FALSE;
954 parse_param_transfer (param, transfer, name);
956 if (scope && strcmp (scope, "call") == 0)
957 param->scope = GI_SCOPE_TYPE_CALL;
958 else if (scope && strcmp (scope, "async") == 0)
959 param->scope = GI_SCOPE_TYPE_ASYNC;
960 else if (scope && strcmp (scope, "notified") == 0)
961 param->scope = GI_SCOPE_TYPE_NOTIFIED;
963 param->scope = GI_SCOPE_TYPE_INVALID;
965 param->closure = closure ? atoi (closure) : -1;
966 param->destroy = destroy ? atoi (destroy) : -1;
968 ((GIrNode *)param)->name = g_strdup (name);
970 switch (CURRENT_NODE (ctx)->type)
972 case G_IR_NODE_FUNCTION:
973 case G_IR_NODE_CALLBACK:
975 GIrNodeFunction *func;
977 func = (GIrNodeFunction *)CURRENT_NODE (ctx);
978 func->parameters = g_list_append (func->parameters, param);
981 case G_IR_NODE_SIGNAL:
983 GIrNodeSignal *signal;
985 signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
986 signal->parameters = g_list_append (signal->parameters, param);
989 case G_IR_NODE_VFUNC:
993 vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
994 vfunc->parameters = g_list_append (vfunc->parameters, param);
998 g_assert_not_reached ();
1005 start_field (GMarkupParseContext *context,
1006 const gchar *element_name,
1007 const gchar **attribute_names,
1008 const gchar **attribute_values,
1013 const gchar *readable;
1014 const gchar *writable;
1016 const gchar *branch;
1017 GIrNodeField *field;
1025 case STATE_INTERFACE:
1031 if (strcmp (element_name, "field") != 0)
1034 name = find_attribute ("name", attribute_names, attribute_values);
1035 readable = find_attribute ("readable", attribute_names, attribute_values);
1036 writable = find_attribute ("writable", attribute_names, attribute_values);
1037 bits = find_attribute ("bits", attribute_names, attribute_values);
1038 branch = find_attribute ("branch", attribute_names, attribute_values);
1042 MISSING_ATTRIBUTE (context, error, element_name, "name");
1046 field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD);
1047 ctx->current_typed = (GIrNode*) field;
1048 ((GIrNode *)field)->name = g_strdup (name);
1049 /* Fields are assumed to be read-only.
1050 * (see also girwriter.py and generate.c)
1052 field->readable = readable == NULL || strcmp (readable, "0") == 0;
1053 field->writable = writable != NULL && strcmp (writable, "1") == 0;
1056 field->bits = atoi (bits);
1060 switch (CURRENT_NODE (ctx)->type)
1062 case G_IR_NODE_OBJECT:
1064 GIrNodeInterface *iface;
1066 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1067 iface->members = g_list_append (iface->members, field);
1068 state_switch (ctx, STATE_CLASS_FIELD);
1071 case G_IR_NODE_INTERFACE:
1073 GIrNodeInterface *iface;
1075 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1076 iface->members = g_list_append (iface->members, field);
1077 state_switch (ctx, STATE_INTERFACE_FIELD);
1080 case G_IR_NODE_BOXED:
1082 GIrNodeBoxed *boxed;
1084 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
1085 boxed->members = g_list_append (boxed->members, field);
1086 state_switch (ctx, STATE_BOXED_FIELD);
1089 case G_IR_NODE_STRUCT:
1091 GIrNodeStruct *struct_;
1093 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
1094 struct_->members = g_list_append (struct_->members, field);
1095 state_switch (ctx, STATE_STRUCT_FIELD);
1098 case G_IR_NODE_UNION:
1100 GIrNodeUnion *union_;
1102 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
1103 union_->members = g_list_append (union_->members, field);
1106 GIrNodeConstant *constant;
1108 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1109 ((GIrNode *)constant)->name = g_strdup (name);
1110 constant->value = g_strdup (branch);
1111 constant->type = union_->discriminator_type;
1112 constant->deprecated = FALSE;
1114 union_->discriminators = g_list_append (union_->discriminators, constant);
1116 state_switch (ctx, STATE_UNION_FIELD);
1120 g_assert_not_reached ();
1127 start_alias (GMarkupParseContext *context,
1128 const gchar *element_name,
1129 const gchar **attribute_names,
1130 const gchar **attribute_values,
1135 const gchar *target;
1139 name = find_attribute ("name", attribute_names, attribute_values);
1142 MISSING_ATTRIBUTE (context, error, element_name, "name");
1146 target = find_attribute ("target", attribute_names, attribute_values);
1149 MISSING_ATTRIBUTE (context, error, element_name, "target");
1153 value = g_strdup (target);
1154 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
1155 if (!strchr (target, '.'))
1157 const BasicTypeInfo *basic = parse_basic (target);
1161 /* For non-basic types, re-qualify the interface */
1162 value = g_strdup_printf ("%s.%s", ctx->namespace, target);
1165 g_hash_table_replace (ctx->aliases, key, value);
1171 start_enum (GMarkupParseContext *context,
1172 const gchar *element_name,
1173 const gchar **attribute_names,
1174 const gchar **attribute_values,
1178 if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
1179 (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))
1182 const gchar *typename;
1183 const gchar *typeinit;
1184 const gchar *deprecated;
1186 name = find_attribute ("name", attribute_names, attribute_values);
1187 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1188 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1189 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1192 MISSING_ATTRIBUTE (context, error, element_name, "name");
1197 if (strcmp (element_name, "enumeration") == 0)
1198 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM);
1200 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS);
1201 ((GIrNode *)enum_)->name = g_strdup (name);
1202 enum_->gtype_name = g_strdup (typename);
1203 enum_->gtype_init = g_strdup (typeinit);
1205 enum_->deprecated = TRUE;
1207 enum_->deprecated = FALSE;
1209 push_node (ctx, (GIrNode *) enum_);
1210 ctx->current_module->entries =
1211 g_list_append (ctx->current_module->entries, enum_);
1213 state_switch (ctx, STATE_ENUM);
1222 start_property (GMarkupParseContext *context,
1223 const gchar *element_name,
1224 const gchar **attribute_names,
1225 const gchar **attribute_values,
1229 if (strcmp (element_name, "property") == 0 &&
1230 (ctx->state == STATE_CLASS ||
1231 ctx->state == STATE_INTERFACE))
1234 const gchar *readable;
1235 const gchar *writable;
1236 const gchar *construct;
1237 const gchar *construct_only;
1239 name = find_attribute ("name", attribute_names, attribute_values);
1240 readable = find_attribute ("readable", attribute_names, attribute_values);
1241 writable = find_attribute ("writable", attribute_names, attribute_values);
1242 construct = find_attribute ("construct", attribute_names, attribute_values);
1243 construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
1246 MISSING_ATTRIBUTE (context, error, element_name, "name");
1249 GIrNodeProperty *property;
1250 GIrNodeInterface *iface;
1252 property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
1253 ctx->current_typed = (GIrNode*) property;
1255 ((GIrNode *)property)->name = g_strdup (name);
1257 /* Assume properties are readable */
1258 if (readable == NULL || strcmp (readable, "1") == 0)
1259 property->readable = TRUE;
1261 property->readable = FALSE;
1262 if (writable && strcmp (writable, "1") == 0)
1263 property->writable = TRUE;
1265 property->writable = FALSE;
1266 if (construct && strcmp (construct, "1") == 0)
1267 property->construct = TRUE;
1269 property->construct = FALSE;
1270 if (construct_only && strcmp (construct_only, "1") == 0)
1271 property->construct_only = TRUE;
1273 property->construct_only = FALSE;
1275 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1276 iface->members = g_list_append (iface->members, property);
1278 if (ctx->state == STATE_CLASS)
1279 state_switch (ctx, STATE_CLASS_PROPERTY);
1280 else if (ctx->state == STATE_INTERFACE)
1281 state_switch (ctx, STATE_INTERFACE_PROPERTY);
1283 g_assert_not_reached ();
1292 parse_value (const gchar *str)
1296 /* FIXME just a quick hack */
1297 shift_op = strstr (str, "<<");
1303 base = strtol (str, NULL, 10);
1304 shift = strtol (shift_op + 3, NULL, 10);
1306 return base << shift;
1309 return strtol (str, NULL, 10);
1315 start_member (GMarkupParseContext *context,
1316 const gchar *element_name,
1317 const gchar **attribute_names,
1318 const gchar **attribute_values,
1322 if (strcmp (element_name, "member") == 0 &&
1323 ctx->state == STATE_ENUM)
1327 const gchar *deprecated;
1329 name = find_attribute ("name", attribute_names, attribute_values);
1330 value = find_attribute ("value", attribute_names, attribute_values);
1331 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1334 MISSING_ATTRIBUTE (context, error, element_name, "name");
1338 GIrNodeValue *value_;
1340 value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
1342 ((GIrNode *)value_)->name = g_strdup (name);
1344 value_->value = parse_value (value);
1347 value_->deprecated = TRUE;
1349 value_->deprecated = FALSE;
1351 enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx);
1352 enum_->values = g_list_append (enum_->values, value_);
1361 start_constant (GMarkupParseContext *context,
1362 const gchar *element_name,
1363 const gchar **attribute_names,
1364 const gchar **attribute_values,
1368 if (strcmp (element_name, "constant") == 0 &&
1369 (ctx->state == STATE_NAMESPACE ||
1370 ctx->state == STATE_CLASS ||
1371 ctx->state == STATE_INTERFACE))
1375 const gchar *deprecated;
1377 name = find_attribute ("name", attribute_names, attribute_values);
1378 value = find_attribute ("value", attribute_names, attribute_values);
1379 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1382 MISSING_ATTRIBUTE (context, error, element_name, "name");
1383 else if (value == NULL)
1384 MISSING_ATTRIBUTE (context, error, element_name, "value");
1387 GIrNodeConstant *constant;
1389 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1391 ((GIrNode *)constant)->name = g_strdup (name);
1392 constant->value = g_strdup (value);
1394 ctx->current_typed = (GIrNode*) constant;
1397 constant->deprecated = TRUE;
1399 constant->deprecated = FALSE;
1401 if (ctx->state == STATE_NAMESPACE)
1403 push_node (ctx, (GIrNode *) constant);
1404 ctx->current_module->entries =
1405 g_list_append (ctx->current_module->entries, constant);
1409 GIrNodeInterface *iface;
1411 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1412 iface->members = g_list_append (iface->members, constant);
1417 case STATE_NAMESPACE:
1418 state_switch (ctx, STATE_NAMESPACE_CONSTANT);
1421 state_switch (ctx, STATE_CLASS_CONSTANT);
1423 case STATE_INTERFACE:
1424 state_switch (ctx, STATE_INTERFACE_CONSTANT);
1427 g_assert_not_reached ();
1438 start_errordomain (GMarkupParseContext *context,
1439 const gchar *element_name,
1440 const gchar **attribute_names,
1441 const gchar **attribute_values,
1445 if (strcmp (element_name, "errordomain") == 0 &&
1446 ctx->state == STATE_NAMESPACE)
1449 const gchar *getquark;
1451 const gchar *deprecated;
1453 name = find_attribute ("name", attribute_names, attribute_values);
1454 getquark = find_attribute ("get-quark", attribute_names, attribute_values);
1455 codes = find_attribute ("codes", attribute_names, attribute_values);
1456 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1459 MISSING_ATTRIBUTE (context, error, element_name, "name");
1460 else if (getquark == NULL)
1461 MISSING_ATTRIBUTE (context, error, element_name, "getquark");
1462 else if (codes == NULL)
1463 MISSING_ATTRIBUTE (context, error, element_name, "codes");
1466 GIrNodeErrorDomain *domain;
1468 domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
1470 ((GIrNode *)domain)->name = g_strdup (name);
1471 domain->getquark = g_strdup (getquark);
1472 domain->codes = g_strdup (codes);
1475 domain->deprecated = TRUE;
1477 domain->deprecated = FALSE;
1479 push_node (ctx, (GIrNode *) domain);
1480 ctx->current_module->entries =
1481 g_list_append (ctx->current_module->entries, domain);
1483 state_switch (ctx, STATE_ERRORDOMAIN);
1492 start_interface (GMarkupParseContext *context,
1493 const gchar *element_name,
1494 const gchar **attribute_names,
1495 const gchar **attribute_values,
1499 if (strcmp (element_name, "interface") == 0 &&
1500 ctx->state == STATE_NAMESPACE)
1503 const gchar *typename;
1504 const gchar *typeinit;
1505 const gchar *deprecated;
1506 const gchar *glib_type_struct;
1508 name = find_attribute ("name", attribute_names, attribute_values);
1509 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1510 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1511 glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values);
1512 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1515 MISSING_ATTRIBUTE (context, error, element_name, "name");
1516 else if (typename == NULL)
1517 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1518 else if (typeinit == NULL)
1519 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1522 GIrNodeInterface *iface;
1524 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE);
1525 ((GIrNode *)iface)->name = g_strdup (name);
1526 iface->gtype_name = g_strdup (typename);
1527 iface->gtype_init = g_strdup (typeinit);
1528 iface->glib_type_struct = g_strdup (glib_type_struct);
1530 iface->deprecated = TRUE;
1532 iface->deprecated = FALSE;
1534 push_node (ctx, (GIrNode *) iface);
1535 ctx->current_module->entries =
1536 g_list_append (ctx->current_module->entries, iface);
1538 state_switch (ctx, STATE_INTERFACE);
1548 start_class (GMarkupParseContext *context,
1549 const gchar *element_name,
1550 const gchar **attribute_names,
1551 const gchar **attribute_values,
1555 if (strcmp (element_name, "class") == 0 &&
1556 ctx->state == STATE_NAMESPACE)
1559 const gchar *parent;
1560 const gchar *glib_type_struct;
1561 const gchar *typename;
1562 const gchar *typeinit;
1563 const gchar *deprecated;
1564 const gchar *abstract;
1566 name = find_attribute ("name", attribute_names, attribute_values);
1567 parent = find_attribute ("parent", attribute_names, attribute_values);
1568 glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values);
1569 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1570 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1571 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1572 abstract = find_attribute ("abstract", attribute_names, attribute_values);
1575 MISSING_ATTRIBUTE (context, error, element_name, "name");
1576 else if (typename == NULL)
1577 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1578 else if (typeinit == NULL && strcmp (typename, "GObject"))
1579 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1582 GIrNodeInterface *iface;
1584 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT);
1585 ((GIrNode *)iface)->name = g_strdup (name);
1586 iface->gtype_name = g_strdup (typename);
1587 iface->gtype_init = g_strdup (typeinit);
1588 iface->parent = g_strdup (parent);
1589 iface->glib_type_struct = g_strdup (glib_type_struct);
1591 iface->deprecated = TRUE;
1593 iface->deprecated = FALSE;
1595 iface->abstract = abstract && strcmp (abstract, "1") == 0;
1597 push_node (ctx, (GIrNode *) iface);
1598 ctx->current_module->entries =
1599 g_list_append (ctx->current_module->entries, iface);
1601 state_switch (ctx, STATE_CLASS);
1610 start_type (GMarkupParseContext *context,
1611 const gchar *element_name,
1612 const gchar **attribute_names,
1613 const gchar **attribute_values,
1620 gboolean is_varargs;
1621 GIrNodeType *typenode;
1623 is_array = strcmp (element_name, "array") == 0;
1624 is_varargs = strcmp (element_name, "varargs") == 0;
1626 if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
1629 if (ctx->state == STATE_TYPE)
1632 ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters);
1633 ctx->type_parameters = NULL;
1635 else if (ctx->state == STATE_FUNCTION_PARAMETER ||
1636 ctx->state == STATE_FUNCTION_RETURN ||
1637 ctx->state == STATE_STRUCT_FIELD ||
1638 ctx->state == STATE_UNION_FIELD ||
1639 ctx->state == STATE_CLASS_PROPERTY ||
1640 ctx->state == STATE_CLASS_FIELD ||
1641 ctx->state == STATE_INTERFACE_FIELD ||
1642 ctx->state == STATE_INTERFACE_PROPERTY ||
1643 ctx->state == STATE_BOXED_FIELD ||
1644 ctx->state == STATE_NAMESPACE_CONSTANT ||
1645 ctx->state == STATE_CLASS_CONSTANT ||
1646 ctx->state == STATE_INTERFACE_CONSTANT
1649 state_switch (ctx, STATE_TYPE);
1650 ctx->type_depth = 1;
1653 switch (CURRENT_NODE (ctx)->type)
1655 case G_IR_NODE_FUNCTION:
1656 case G_IR_NODE_CALLBACK:
1658 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1659 func->is_varargs = TRUE;
1662 case G_IR_NODE_VFUNC:
1664 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1665 vfunc->is_varargs = TRUE;
1668 /* list others individually rather than with default: so that compiler
1669 * warns if new node types are added without adding them to the switch
1671 case G_IR_NODE_INVALID:
1672 case G_IR_NODE_ENUM:
1673 case G_IR_NODE_FLAGS:
1674 case G_IR_NODE_CONSTANT:
1675 case G_IR_NODE_ERROR_DOMAIN:
1676 case G_IR_NODE_PARAM:
1677 case G_IR_NODE_TYPE:
1678 case G_IR_NODE_PROPERTY:
1679 case G_IR_NODE_SIGNAL:
1680 case G_IR_NODE_VALUE:
1681 case G_IR_NODE_FIELD:
1682 case G_IR_NODE_XREF:
1683 case G_IR_NODE_STRUCT:
1684 case G_IR_NODE_BOXED:
1685 case G_IR_NODE_OBJECT:
1686 case G_IR_NODE_INTERFACE:
1687 case G_IR_NODE_UNION:
1688 g_assert_not_reached ();
1692 ctx->type_stack = NULL;
1693 ctx->type_parameters = NULL;
1696 if (!ctx->current_typed)
1700 G_MARKUP_ERROR_INVALID_CONTENT,
1701 "The element <type> is invalid here");
1714 typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
1716 typenode->tag = GI_TYPE_TAG_ARRAY;
1717 typenode->is_pointer = TRUE;
1718 typenode->is_array = TRUE;
1720 zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
1721 len = find_attribute ("length", attribute_names, attribute_values);
1722 size = find_attribute ("fixed-size", attribute_names, attribute_values);
1724 typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0);
1725 typenode->has_length = len != NULL;
1726 typenode->length = typenode->has_length ? atoi (len) : -1;
1728 typenode->has_size = size != NULL;
1729 typenode->size = typenode->has_size ? atoi (size) : -1;
1732 typenode->zero_terminated = strcmp(zero, "1") == 0;
1734 /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */
1735 typenode->zero_terminated = !(typenode->has_length || typenode->has_size);
1740 name = find_attribute ("name", attribute_names, attribute_values);
1743 MISSING_ATTRIBUTE (context, error, element_name, "name");
1746 ctype = find_attribute ("c:type", attribute_names, attribute_values);
1749 const char *cp = ctype + strlen(ctype) - 1;
1750 while (cp > ctype && *cp-- == '*')
1754 if (ctx->current_typed->type == G_IR_NODE_PARAM &&
1755 ((GIrNodeParam *)ctx->current_typed)->out &&
1759 typenode = parse_type (ctx, name);
1761 /* A 'disguised' structure is one where the c:type is a typedef that
1762 * doesn't look like a pointer, but is internally.
1764 if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
1765 is_disguised_structure (ctx, typenode->interface))
1768 if (pointer_depth > 0)
1769 typenode->is_pointer = TRUE;
1772 ctx->type_parameters = g_list_append (ctx->type_parameters, typenode);
1778 end_type_top (ParseContext *ctx)
1780 GIrNodeType *typenode;
1782 if (!ctx->type_parameters)
1785 typenode = (GIrNodeType*)ctx->type_parameters->data;
1787 /* Default to pointer for unspecified containers */
1788 if (typenode->tag == GI_TYPE_TAG_ARRAY ||
1789 typenode->tag == GI_TYPE_TAG_GLIST ||
1790 typenode->tag == GI_TYPE_TAG_GSLIST)
1792 if (typenode->parameter_type1 == NULL)
1793 typenode->parameter_type1 = parse_type (ctx, "any");
1795 else if (typenode->tag == GI_TYPE_TAG_GHASH)
1797 if (typenode->parameter_type1 == NULL)
1799 typenode->parameter_type1 = parse_type (ctx, "any");
1800 typenode->parameter_type2 = parse_type (ctx, "any");
1804 switch (ctx->current_typed->type)
1806 case G_IR_NODE_PARAM:
1808 GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed;
1809 param->type = typenode;
1812 case G_IR_NODE_FIELD:
1814 GIrNodeField *field = (GIrNodeField *)ctx->current_typed;
1815 field->type = typenode;
1818 case G_IR_NODE_PROPERTY:
1820 GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed;
1821 property->type = typenode;
1824 case G_IR_NODE_CONSTANT:
1826 GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed;
1827 constant->type = typenode;
1831 g_printerr("current node is %d\n", CURRENT_NODE (ctx)->type);
1832 g_assert_not_reached ();
1834 g_list_free (ctx->type_parameters);
1837 ctx->type_depth = 0;
1838 ctx->type_parameters = NULL;
1839 ctx->current_typed = NULL;
1843 end_type_recurse (ParseContext *ctx)
1845 GIrNodeType *parent;
1846 GIrNodeType *param = NULL;
1848 parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data;
1849 if (ctx->type_parameters)
1850 param = (GIrNodeType *) ctx->type_parameters->data;
1852 if (parent->tag == GI_TYPE_TAG_ARRAY ||
1853 parent->tag == GI_TYPE_TAG_GLIST ||
1854 parent->tag == GI_TYPE_TAG_GSLIST)
1856 g_assert (param != NULL);
1858 if (parent->parameter_type1 == NULL)
1859 parent->parameter_type1 = param;
1861 g_assert_not_reached ();
1863 else if (parent->tag == GI_TYPE_TAG_GHASH)
1865 g_assert (param != NULL);
1867 if (parent->parameter_type1 == NULL)
1868 parent->parameter_type1 = param;
1869 else if (parent->parameter_type2 == NULL)
1870 parent->parameter_type2 = param;
1872 g_assert_not_reached ();
1874 g_list_free (ctx->type_parameters);
1875 ctx->type_parameters = (GList *)ctx->type_stack->data;
1876 ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
1880 end_type (ParseContext *ctx)
1882 if (ctx->type_depth == 1)
1885 state_switch (ctx, ctx->prev_state);
1889 end_type_recurse (ctx);
1895 start_attribute (GMarkupParseContext *context,
1896 const gchar *element_name,
1897 const gchar **attribute_names,
1898 const gchar **attribute_values,
1906 if (strcmp (element_name, "attribute") != 0 || ctx->node_stack == NULL)
1909 name = find_attribute ("name", attribute_names, attribute_values);
1910 value = find_attribute ("value", attribute_names, attribute_values);
1914 MISSING_ATTRIBUTE (context, error, element_name, "name");
1919 MISSING_ATTRIBUTE (context, error, element_name, "value");
1923 state_switch (ctx, STATE_ATTRIBUTE);
1925 curnode = CURRENT_NODE (ctx);
1927 g_hash_table_insert (curnode->attributes, g_strdup (name), g_strdup (value));
1933 start_return_value (GMarkupParseContext *context,
1934 const gchar *element_name,
1935 const gchar **attribute_names,
1936 const gchar **attribute_values,
1940 if (strcmp (element_name, "return-value") == 0 &&
1941 ctx->state == STATE_FUNCTION)
1943 GIrNodeParam *param;
1944 const gchar *transfer;
1946 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
1949 param->retval = TRUE;
1951 ctx->current_typed = (GIrNode*) param;
1953 state_switch (ctx, STATE_FUNCTION_RETURN);
1955 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1956 parse_param_transfer (param, transfer, NULL);
1958 switch (CURRENT_NODE (ctx)->type)
1960 case G_IR_NODE_FUNCTION:
1961 case G_IR_NODE_CALLBACK:
1963 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1964 func->result = param;
1967 case G_IR_NODE_SIGNAL:
1969 GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
1970 signal->result = param;
1973 case G_IR_NODE_VFUNC:
1975 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1976 vfunc->result = param;
1980 g_assert_not_reached ();
1990 start_implements (GMarkupParseContext *context,
1991 const gchar *element_name,
1992 const gchar **attribute_names,
1993 const gchar **attribute_values,
1997 GIrNodeInterface *iface;
2000 if (strcmp (element_name, "implements") != 0 ||
2001 !(ctx->state == STATE_CLASS))
2004 state_switch (ctx, STATE_IMPLEMENTS);
2006 name = find_attribute ("name", attribute_names, attribute_values);
2009 MISSING_ATTRIBUTE (context, error, element_name, "name");
2013 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2014 iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
2020 start_glib_signal (GMarkupParseContext *context,
2021 const gchar *element_name,
2022 const gchar **attribute_names,
2023 const gchar **attribute_values,
2027 if (strcmp (element_name, "glib:signal") == 0 &&
2028 (ctx->state == STATE_CLASS ||
2029 ctx->state == STATE_INTERFACE))
2033 const gchar *no_recurse;
2034 const gchar *detailed;
2035 const gchar *action;
2036 const gchar *no_hooks;
2037 const gchar *has_class_closure;
2039 name = find_attribute ("name", attribute_names, attribute_values);
2040 when = find_attribute ("when", attribute_names, attribute_values);
2041 no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values);
2042 detailed = find_attribute ("detailed", attribute_names, attribute_values);
2043 action = find_attribute ("action", attribute_names, attribute_values);
2044 no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values);
2045 has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values);
2048 MISSING_ATTRIBUTE (context, error, element_name, "name");
2051 GIrNodeInterface *iface;
2052 GIrNodeSignal *signal;
2054 signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
2056 ((GIrNode *)signal)->name = g_strdup (name);
2058 signal->run_first = FALSE;
2059 signal->run_last = FALSE;
2060 signal->run_cleanup = FALSE;
2061 if (when == NULL || strcmp (when, "LAST") == 0)
2062 signal->run_last = TRUE;
2063 else if (strcmp (when, "FIRST") == 0)
2064 signal->run_first = TRUE;
2066 signal->run_cleanup = TRUE;
2068 if (no_recurse && strcmp (no_recurse, "1") == 0)
2069 signal->no_recurse = TRUE;
2071 signal->no_recurse = FALSE;
2072 if (detailed && strcmp (detailed, "1") == 0)
2073 signal->detailed = TRUE;
2075 signal->detailed = FALSE;
2076 if (action && strcmp (action, "1") == 0)
2077 signal->action = TRUE;
2079 signal->action = FALSE;
2080 if (no_hooks && strcmp (no_hooks, "1") == 0)
2081 signal->no_hooks = TRUE;
2083 signal->no_hooks = FALSE;
2084 if (has_class_closure && strcmp (has_class_closure, "1") == 0)
2085 signal->has_class_closure = TRUE;
2087 signal->has_class_closure = FALSE;
2089 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2090 iface->members = g_list_append (iface->members, signal);
2092 push_node (ctx, (GIrNode *)signal);
2093 state_switch (ctx, STATE_FUNCTION);
2102 start_vfunc (GMarkupParseContext *context,
2103 const gchar *element_name,
2104 const gchar **attribute_names,
2105 const gchar **attribute_values,
2109 if (strcmp (element_name, "virtual-method") == 0 &&
2110 (ctx->state == STATE_CLASS ||
2111 ctx->state == STATE_INTERFACE))
2114 const gchar *must_chain_up;
2115 const gchar *override;
2116 const gchar *is_class_closure;
2117 const gchar *offset;
2118 const gchar *invoker;
2120 name = find_attribute ("name", attribute_names, attribute_values);
2121 must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values);
2122 override = find_attribute ("override", attribute_names, attribute_values);
2123 is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values);
2124 offset = find_attribute ("offset", attribute_names, attribute_values);
2125 invoker = find_attribute ("invoker", attribute_names, attribute_values);
2128 MISSING_ATTRIBUTE (context, error, element_name, "name");
2131 GIrNodeInterface *iface;
2132 GIrNodeVFunc *vfunc;
2134 vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
2136 ((GIrNode *)vfunc)->name = g_strdup (name);
2138 if (must_chain_up && strcmp (must_chain_up, "1") == 0)
2139 vfunc->must_chain_up = TRUE;
2141 vfunc->must_chain_up = FALSE;
2143 if (override && strcmp (override, "always") == 0)
2145 vfunc->must_be_implemented = TRUE;
2146 vfunc->must_not_be_implemented = FALSE;
2148 else if (override && strcmp (override, "never") == 0)
2150 vfunc->must_be_implemented = FALSE;
2151 vfunc->must_not_be_implemented = TRUE;
2155 vfunc->must_be_implemented = FALSE;
2156 vfunc->must_not_be_implemented = FALSE;
2159 if (is_class_closure && strcmp (is_class_closure, "1") == 0)
2160 vfunc->is_class_closure = TRUE;
2162 vfunc->is_class_closure = FALSE;
2165 vfunc->offset = atoi (offset);
2169 vfunc->invoker = g_strdup (invoker);
2171 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2172 iface->members = g_list_append (iface->members, vfunc);
2174 push_node (ctx, (GIrNode *)vfunc);
2175 state_switch (ctx, STATE_FUNCTION);
2185 start_struct (GMarkupParseContext *context,
2186 const gchar *element_name,
2187 const gchar **attribute_names,
2188 const gchar **attribute_values,
2192 if (strcmp (element_name, "record") == 0 &&
2193 (ctx->state == STATE_NAMESPACE ||
2194 ctx->state == STATE_UNION ||
2195 ctx->state == STATE_STRUCT ||
2196 ctx->state == STATE_CLASS))
2199 const gchar *deprecated;
2200 const gchar *disguised;
2201 const gchar *gtype_name;
2202 const gchar *gtype_init;
2203 const gchar *gtype_struct;
2204 const gchar *foreign;
2205 GIrNodeStruct *struct_;
2207 name = find_attribute ("name", attribute_names, attribute_values);
2208 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2209 disguised = find_attribute ("disguised", attribute_names, attribute_values);
2210 gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
2211 gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
2212 gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values);
2213 foreign = find_attribute ("foreign", attribute_names, attribute_values);
2215 if (name == NULL && ctx->node_stack == NULL)
2217 MISSING_ATTRIBUTE (context, error, element_name, "name");
2220 if ((gtype_name == NULL && gtype_init != NULL))
2222 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
2225 if ((gtype_name != NULL && gtype_init == NULL))
2227 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
2231 struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
2233 ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
2235 struct_->deprecated = TRUE;
2237 struct_->deprecated = FALSE;
2239 if (disguised && strcmp (disguised, "1") == 0)
2240 struct_->disguised = TRUE;
2242 struct_->is_gtype_struct = gtype_struct != NULL;
2244 struct_->gtype_name = g_strdup (gtype_name);
2245 struct_->gtype_init = g_strdup (gtype_init);
2247 struct_->foreign = (g_strcmp0 (foreign, "1") == 0);
2249 if (ctx->node_stack == NULL)
2250 ctx->current_module->entries =
2251 g_list_append (ctx->current_module->entries, struct_);
2252 push_node (ctx, (GIrNode *)struct_);
2254 state_switch (ctx, STATE_STRUCT);
2262 start_union (GMarkupParseContext *context,
2263 const gchar *element_name,
2264 const gchar **attribute_names,
2265 const gchar **attribute_values,
2269 if (strcmp (element_name, "union") == 0 &&
2270 (ctx->state == STATE_NAMESPACE ||
2271 ctx->state == STATE_UNION ||
2272 ctx->state == STATE_STRUCT ||
2273 ctx->state == STATE_CLASS))
2276 const gchar *deprecated;
2277 const gchar *typename;
2278 const gchar *typeinit;
2280 name = find_attribute ("name", attribute_names, attribute_values);
2281 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2282 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
2283 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
2285 if (name == NULL && ctx->node_stack == NULL)
2286 MISSING_ATTRIBUTE (context, error, element_name, "name");
2289 GIrNodeUnion *union_;
2291 union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
2293 ((GIrNode *)union_)->name = g_strdup (name ? name : "");
2294 union_->gtype_name = g_strdup (typename);
2295 union_->gtype_init = g_strdup (typeinit);
2297 union_->deprecated = TRUE;
2299 union_->deprecated = FALSE;
2301 if (ctx->node_stack == NULL)
2302 ctx->current_module->entries =
2303 g_list_append (ctx->current_module->entries, union_);
2304 push_node (ctx, (GIrNode *)union_);
2306 state_switch (ctx, STATE_UNION);
2314 start_discriminator (GMarkupParseContext *context,
2315 const gchar *element_name,
2316 const gchar **attribute_names,
2317 const gchar **attribute_values,
2321 if (strcmp (element_name, "discriminator") == 0 &&
2322 ctx->state == STATE_UNION)
2325 const gchar *offset;
2327 type = find_attribute ("type", attribute_names, attribute_values);
2328 offset = find_attribute ("offset", attribute_names, attribute_values);
2330 MISSING_ATTRIBUTE (context, error, element_name, "type");
2331 else if (offset == NULL)
2332 MISSING_ATTRIBUTE (context, error, element_name, "offset");
2334 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type
2335 = parse_type (ctx, type);
2336 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset
2347 parse_include (GMarkupParseContext *context,
2350 const char *version,
2355 gchar *girpath, *girname;
2356 gboolean success = FALSE;
2360 for (l = ctx->parser->parsed_modules; l; l = l->next)
2362 GIrModule *m = l->data;
2364 if (strcmp (m->name, name) == 0)
2366 if (strcmp (m->version, version) == 0)
2368 ctx->include_modules = g_list_prepend (ctx->include_modules, m);
2376 G_MARKUP_ERROR_INVALID_CONTENT,
2377 "Module '%s' imported with conflicting versions '%s' and '%s'",
2378 name, m->version, version);
2384 girname = g_strdup_printf ("%s-%s.gir", name, version);
2385 girpath = locate_gir (ctx->parser, girname);
2387 if (girpath == NULL)
2391 G_MARKUP_ERROR_INVALID_CONTENT,
2392 "Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir",
2399 g_debug ("Parsing include %s", girpath);
2401 if (!g_file_get_contents (girpath, &buffer, &length, error))
2408 modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error);
2409 success = error != NULL;
2411 ctx->include_modules = g_list_concat (ctx->include_modules,
2419 extern GLogLevelFlags logged_levels;
2422 start_element_handler (GMarkupParseContext *context,
2423 const gchar *element_name,
2424 const gchar **attribute_names,
2425 const gchar **attribute_values,
2429 ParseContext *ctx = user_data;
2430 gint line_number, char_number;
2432 if (logged_levels & G_LOG_LEVEL_DEBUG)
2434 GString *tags = g_string_new ("");
2436 for (i = 0; attribute_names[i]; i++)
2437 g_string_append_printf (tags, "%s=\"%s\" ",
2439 attribute_values[i]);
2443 g_string_insert_c (tags, 0, ' ');
2444 g_string_truncate (tags, tags->len - 1);
2446 g_debug ("<%s%s>", element_name, tags->str);
2447 g_string_free (tags, TRUE);
2450 switch (element_name[0])
2453 if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0)
2455 state_switch (ctx, STATE_ALIAS);
2458 if (start_type (context, element_name,
2459 attribute_names, attribute_values,
2462 else if (start_attribute (context, element_name,
2463 attribute_names, attribute_values,
2468 if (start_enum (context, element_name,
2469 attribute_names, attribute_values,
2474 if (start_function (context, element_name,
2475 attribute_names, attribute_values,
2478 else if (start_constant (context, element_name,
2479 attribute_names, attribute_values,
2482 else if (start_class (context, element_name,
2483 attribute_names, attribute_values,
2489 if (start_discriminator (context, element_name,
2490 attribute_names, attribute_values,
2496 if (start_enum (context, element_name,
2497 attribute_names, attribute_values,
2500 else if (start_errordomain (context, element_name,
2501 attribute_names, attribute_values,
2507 if (start_function (context, element_name,
2508 attribute_names, attribute_values,
2511 else if (start_field (context, element_name,
2512 attribute_names, attribute_values,
2518 if (start_glib_boxed (context, element_name,
2519 attribute_names, attribute_values,
2522 else if (start_glib_signal (context, element_name,
2523 attribute_names, attribute_values,
2529 if (strcmp (element_name, "include") == 0 &&
2530 ctx->state == STATE_REPOSITORY)
2533 const gchar *version;
2535 name = find_attribute ("name", attribute_names, attribute_values);
2536 version = find_attribute ("version", attribute_names, attribute_values);
2540 MISSING_ATTRIBUTE (context, error, element_name, "name");
2543 if (version == NULL)
2545 MISSING_ATTRIBUTE (context, error, element_name, "version");
2549 if (!parse_include (context, ctx, name, version, error))
2552 ctx->dependencies = g_list_prepend (ctx->dependencies,
2553 g_strdup_printf ("%s-%s", name, version));
2556 state_switch (ctx, STATE_INCLUDE);
2559 if (start_interface (context, element_name,
2560 attribute_names, attribute_values,
2563 else if (start_implements (context, element_name,
2564 attribute_names, attribute_values,
2570 if (start_function (context, element_name,
2571 attribute_names, attribute_values,
2574 else if (start_member (context, element_name,
2575 attribute_names, attribute_values,
2581 if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2583 const gchar *name, *version, *shared_library, *cprefix;
2585 if (ctx->current_module != NULL)
2589 G_MARKUP_ERROR_INVALID_CONTENT,
2590 "Only one <namespace/> element is currently allowed per <repository/>");
2594 name = find_attribute ("name", attribute_names, attribute_values);
2595 version = find_attribute ("version", attribute_names, attribute_values);
2596 shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2597 cprefix = find_attribute ("c:prefix", attribute_names, attribute_values);
2600 MISSING_ATTRIBUTE (context, error, element_name, "name");
2601 else if (version == NULL)
2602 MISSING_ATTRIBUTE (context, error, element_name, "version");
2607 if (strcmp (name, ctx->namespace) != 0)
2610 G_MARKUP_ERROR_INVALID_CONTENT,
2611 "<namespace/> name element '%s' doesn't match file name '%s'",
2612 name, ctx->namespace);
2614 ctx->current_module = g_ir_module_new (name, version, shared_library, cprefix);
2616 ctx->current_module->aliases = ctx->aliases;
2617 ctx->aliases = NULL;
2618 ctx->current_module->disguised_structures = ctx->disguised_structures;
2619 ctx->disguised_structures = NULL;
2621 for (l = ctx->include_modules; l; l = l->next)
2622 g_ir_module_add_include_module (ctx->current_module, l->data);
2624 g_list_free (ctx->include_modules);
2625 ctx->include_modules = NULL;
2627 ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2628 ctx->current_module->dependencies = ctx->dependencies;
2630 state_switch (ctx, STATE_NAMESPACE);
2637 if (start_property (context, element_name,
2638 attribute_names, attribute_values,
2641 else if (strcmp (element_name, "parameters") == 0 &&
2642 ctx->state == STATE_FUNCTION)
2644 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2648 else if (start_parameter (context, element_name,
2649 attribute_names, attribute_values,
2652 else if (strcmp (element_name, "prerequisite") == 0 &&
2653 ctx->state == STATE_INTERFACE)
2657 name = find_attribute ("name", attribute_names, attribute_values);
2659 state_switch (ctx, STATE_PREREQUISITE);
2662 MISSING_ATTRIBUTE (context, error, element_name, "name");
2665 GIrNodeInterface *iface;
2667 iface = (GIrNodeInterface *)CURRENT_NODE(ctx);
2668 iface->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
2672 else if (strcmp (element_name, "package") == 0 &&
2673 ctx->state == STATE_REPOSITORY)
2675 state_switch (ctx, STATE_PACKAGE);
2681 if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
2683 const gchar *version;
2685 version = find_attribute ("version", attribute_names, attribute_values);
2687 if (version == NULL)
2688 MISSING_ATTRIBUTE (context, error, element_name, "version");
2689 else if (strcmp (version, "1.0") != 0)
2692 G_MARKUP_ERROR_INVALID_CONTENT,
2693 "Unsupported version '%s'",
2696 state_switch (ctx, STATE_REPOSITORY);
2700 else if (start_return_value (context, element_name,
2701 attribute_names, attribute_values,
2704 else if (start_struct (context, element_name,
2705 attribute_names, attribute_values,
2711 if (start_union (context, element_name,
2712 attribute_names, attribute_values,
2718 if (start_type (context, element_name,
2719 attribute_names, attribute_values,
2725 if (start_vfunc (context, element_name,
2726 attribute_names, attribute_values,
2729 if (start_type (context, element_name,
2730 attribute_names, attribute_values,
2736 if (ctx->state != STATE_UNKNOWN)
2738 state_switch (ctx, STATE_UNKNOWN);
2739 ctx->unknown_depth = 1;
2743 ctx->unknown_depth += 1;
2749 g_markup_parse_context_get_position (context, &line_number, &char_number);
2751 fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message);
2752 backtrace_stderr ();
2757 require_one_of_end_elements (GMarkupParseContext *context,
2759 const char *actual_name,
2764 int line_number, char_number;
2765 const char *expected;
2766 gboolean matched = FALSE;
2768 va_start (args, error);
2770 while ((expected = va_arg (args, const char*)) != NULL)
2772 if (strcmp (expected, actual_name) == 0)
2784 g_markup_parse_context_get_position (context, &line_number, &char_number);
2787 G_MARKUP_ERROR_INVALID_CONTENT,
2788 "Unexpected end tag '%s' on line %d char %d; current state=%d",
2790 line_number, char_number, ctx->state);
2796 state_switch_end_struct_or_union (GMarkupParseContext *context,
2798 const gchar *element_name,
2802 if (ctx->node_stack == NULL)
2804 state_switch (ctx, STATE_NAMESPACE);
2808 if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2809 state_switch (ctx, STATE_STRUCT);
2810 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2811 state_switch (ctx, STATE_UNION);
2812 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2813 state_switch (ctx, STATE_CLASS);
2816 int line_number, char_number;
2817 g_markup_parse_context_get_position (context, &line_number, &char_number);
2820 G_MARKUP_ERROR_INVALID_CONTENT,
2821 "Unexpected end tag '%s' on line %d char %d",
2823 line_number, char_number);
2831 require_end_element (GMarkupParseContext *context,
2833 const char *expected_name,
2834 const char *actual_name,
2837 return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
2841 end_element_handler (GMarkupParseContext *context,
2842 const gchar *element_name,
2846 ParseContext *ctx = user_data;
2848 g_debug ("</%s>", element_name);
2854 /* no need to GError here, GMarkup already catches this */
2857 case STATE_REPOSITORY:
2858 state_switch (ctx, STATE_END);
2862 if (require_end_element (context, ctx, "include", element_name, error))
2864 state_switch (ctx, STATE_REPOSITORY);
2869 if (require_end_element (context, ctx, "package", element_name, error))
2871 state_switch (ctx, STATE_REPOSITORY);
2875 case STATE_NAMESPACE:
2876 if (require_end_element (context, ctx, "namespace", element_name, error))
2878 ctx->current_module = NULL;
2879 state_switch (ctx, STATE_REPOSITORY);
2884 if (require_end_element (context, ctx, "alias", element_name, error))
2886 state_switch (ctx, STATE_NAMESPACE);
2890 case STATE_FUNCTION_RETURN:
2891 if (strcmp ("type", element_name) == 0)
2893 if (require_end_element (context, ctx, "return-value", element_name, error))
2895 state_switch (ctx, STATE_FUNCTION);
2899 case STATE_FUNCTION_PARAMETERS:
2900 if (require_end_element (context, ctx, "parameters", element_name, error))
2902 state_switch (ctx, STATE_FUNCTION);
2906 case STATE_FUNCTION_PARAMETER:
2907 if (strcmp ("type", element_name) == 0)
2909 if (require_end_element (context, ctx, "parameter", element_name, error))
2911 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2915 case STATE_FUNCTION:
2918 if (ctx->node_stack == NULL)
2920 state_switch (ctx, STATE_NAMESPACE);
2924 g_debug("case STATE_FUNCTION %d", CURRENT_NODE (ctx)->type);
2925 if (ctx->in_embedded_type)
2927 ctx->in_embedded_type = FALSE;
2928 state_switch (ctx, STATE_STRUCT_FIELD);
2930 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
2931 state_switch (ctx, STATE_INTERFACE);
2932 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2933 state_switch (ctx, STATE_CLASS);
2934 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_BOXED)
2935 state_switch (ctx, STATE_BOXED);
2936 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2937 state_switch (ctx, STATE_STRUCT);
2938 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2939 state_switch (ctx, STATE_UNION);
2942 int line_number, char_number;
2943 g_markup_parse_context_get_position (context, &line_number, &char_number);
2946 G_MARKUP_ERROR_INVALID_CONTENT,
2947 "Unexpected end tag '%s' on line %d char %d",
2949 line_number, char_number);
2955 case STATE_CLASS_FIELD:
2956 if (strcmp ("type", element_name) == 0)
2958 if (require_end_element (context, ctx, "field", element_name, error))
2960 state_switch (ctx, STATE_CLASS);
2964 case STATE_CLASS_PROPERTY:
2965 if (strcmp ("type", element_name) == 0)
2967 if (require_end_element (context, ctx, "property", element_name, error))
2969 state_switch (ctx, STATE_CLASS);
2974 if (require_end_element (context, ctx, "class", element_name, error))
2977 state_switch (ctx, STATE_NAMESPACE);
2981 case STATE_ERRORDOMAIN:
2982 if (require_end_element (context, ctx, "errordomain", element_name, error))
2985 state_switch (ctx, STATE_NAMESPACE);
2989 case STATE_INTERFACE_PROPERTY:
2990 if (strcmp ("type", element_name) == 0)
2992 if (require_end_element (context, ctx, "property", element_name, error))
2994 state_switch (ctx, STATE_INTERFACE);
2998 case STATE_INTERFACE_FIELD:
2999 if (strcmp ("type", element_name) == 0)
3001 if (require_end_element (context, ctx, "field", element_name, error))
3003 state_switch (ctx, STATE_INTERFACE);
3007 case STATE_INTERFACE:
3008 if (require_end_element (context, ctx, "interface", element_name, error))
3011 state_switch (ctx, STATE_NAMESPACE);
3016 if (strcmp ("member", element_name) == 0)
3018 else if (require_one_of_end_elements (context, ctx,
3019 element_name, error, "enumeration",
3023 state_switch (ctx, STATE_NAMESPACE);
3028 if (require_end_element (context, ctx, "glib:boxed", element_name, error))
3031 state_switch (ctx, STATE_NAMESPACE);
3035 case STATE_BOXED_FIELD:
3036 if (strcmp ("type", element_name) == 0)
3038 if (require_end_element (context, ctx, "field", element_name, error))
3040 state_switch (ctx, STATE_BOXED);
3044 case STATE_STRUCT_FIELD:
3045 if (strcmp ("type", element_name) == 0)
3047 if (require_end_element (context, ctx, "field", element_name, error))
3049 state_switch (ctx, STATE_STRUCT);
3054 if (require_end_element (context, ctx, "record", element_name, error))
3056 state_switch_end_struct_or_union (context, ctx, element_name, error);
3060 case STATE_UNION_FIELD:
3061 if (strcmp ("type", element_name) == 0)
3063 if (require_end_element (context, ctx, "field", element_name, error))
3065 state_switch (ctx, STATE_UNION);
3070 if (require_end_element (context, ctx, "union", element_name, error))
3072 state_switch_end_struct_or_union (context, ctx, element_name, error);
3075 case STATE_IMPLEMENTS:
3076 if (strcmp ("interface", element_name) == 0)
3078 if (require_end_element (context, ctx, "implements", element_name, error))
3079 state_switch (ctx, STATE_CLASS);
3081 case STATE_PREREQUISITE:
3082 if (require_end_element (context, ctx, "prerequisite", element_name, error))
3083 state_switch (ctx, STATE_INTERFACE);
3085 case STATE_NAMESPACE_CONSTANT:
3086 case STATE_CLASS_CONSTANT:
3087 case STATE_INTERFACE_CONSTANT:
3088 if (strcmp ("type", element_name) == 0)
3090 if (require_end_element (context, ctx, "constant", element_name, error))
3094 case STATE_NAMESPACE_CONSTANT:
3096 state_switch (ctx, STATE_NAMESPACE);
3098 case STATE_CLASS_CONSTANT:
3099 state_switch (ctx, STATE_CLASS);
3101 case STATE_INTERFACE_CONSTANT:
3102 state_switch (ctx, STATE_INTERFACE);
3105 g_assert_not_reached ();
3111 if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
3112 (strcmp ("varargs", element_name) == 0))
3117 case STATE_ATTRIBUTE:
3118 if (strcmp ("attribute", element_name) == 0)
3120 state_switch (ctx, ctx->prev_state);
3125 ctx->unknown_depth -= 1;
3126 if (ctx->unknown_depth == 0)
3127 state_switch (ctx, ctx->prev_state);
3130 g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
3135 text_handler (GMarkupParseContext *context,
3141 /* FIXME warn about non-whitespace text */
3145 cleanup (GMarkupParseContext *context,
3149 ParseContext *ctx = user_data;
3152 for (m = ctx->modules; m; m = m->next)
3153 g_ir_module_free (m->data);
3154 g_list_free (ctx->modules);
3155 ctx->modules = NULL;
3157 ctx->current_module = NULL;
3161 post_filter_toplevel_varargs_functions (GList *list,
3162 GList **varargs_callbacks_out)
3165 GList *varargs_callbacks = *varargs_callbacks_out;
3171 GIrNode *node = iter->data;
3175 if (node->type == G_IR_NODE_FUNCTION)
3177 if (((GIrNodeFunction*)node)->is_varargs)
3179 list = g_list_delete_link (list, link);
3182 if (node->type == G_IR_NODE_CALLBACK)
3184 if (((GIrNodeFunction*)node)->is_varargs)
3186 varargs_callbacks = g_list_append (varargs_callbacks,
3188 list = g_list_delete_link (list, link);
3193 *varargs_callbacks_out = varargs_callbacks;
3201 quick look up of node in the list..
3202 return null, or a pointer to the list item..
3205 node_find_in_list(GList *list, const char *name)
3212 if (!strcmp (name, ((GIrNode *)link->data)->name))
3221 post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out)
3224 GList *varargs_callbacks;
3226 list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out);
3228 varargs_callbacks = *varargs_callbacks_out;
3234 GIrNode *node = iter->data;
3238 if (node->type == G_IR_NODE_FUNCTION)
3241 gboolean function_done = FALSE;
3243 for (param = ((GIrNodeFunction *)node)->parameters;
3245 param = param->next)
3247 GIrNodeParam *node = (GIrNodeParam *)param->data;
3252 if (node->type->is_interface)
3255 GList *callback = node_find_in_list(
3257 ((GIrNode *)callback->data)->name));
3260 list = g_list_delete_link (list, link);
3261 function_done = TRUE;
3269 *varargs_callbacks_out = varargs_callbacks;
3275 post_filter (GIrModule *module)
3278 GList *varargs_callbacks = NULL;
3280 module->entries = post_filter_varargs_functions (module->entries,
3281 &varargs_callbacks);
3282 iter = module->entries;
3285 GIrNode *node = iter->data;
3289 if (node->type == G_IR_NODE_OBJECT ||
3290 node->type == G_IR_NODE_INTERFACE)
3292 GIrNodeInterface *iface = (GIrNodeInterface*)node;
3293 iface->members = post_filter_varargs_functions (iface->members,
3294 &varargs_callbacks);
3296 else if (node->type == G_IR_NODE_BOXED)
3298 GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
3299 boxed->members = post_filter_varargs_functions (boxed->members,
3300 &varargs_callbacks);
3302 else if (node->type == G_IR_NODE_STRUCT)
3304 GIrNodeStruct *iface = (GIrNodeStruct*)node;
3305 iface->members = post_filter_varargs_functions (iface->members,
3306 &varargs_callbacks);
3308 else if (node->type == G_IR_NODE_UNION)
3310 GIrNodeUnion *iface = (GIrNodeUnion*)node;
3311 iface->members = post_filter_varargs_functions (iface->members,
3312 &varargs_callbacks);
3315 g_list_free (varargs_callbacks);
3319 * g_ir_parser_parse_string:
3320 * @parser: a #GIrParser
3321 * @namespace: the namespace of the string
3322 * @buffer: the data containing the XML
3323 * @length: length of the data
3324 * @error: return location for a #GError, or %NULL
3326 * Parse a string that holds a complete GIR XML file, and return a list of a
3327 * a #GirModule for each <namespace/> element within the file.
3329 * Returns: a newly allocated list of #GIrModule. The modules themselves
3330 * are owned by the #GIrParser and will be freed along with the parser.
3333 g_ir_parser_parse_string (GIrParser *parser,
3334 const gchar *namespace,
3335 const gchar *buffer,
3339 ParseContext ctx = { 0 };
3340 GMarkupParseContext *context;
3342 ctx.parser = parser;
3343 ctx.state = STATE_START;
3344 ctx.namespace = namespace;
3345 ctx.include_modules = NULL;
3346 ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
3347 ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
3349 ctx.dependencies = NULL;
3350 ctx.current_module = NULL;
3352 context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
3354 if (!g_markup_parse_context_parse (context, buffer, length, error))
3357 if (!g_markup_parse_context_end_parse (context, error))
3360 g_markup_parse_context_free (context);
3362 context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL);
3363 if (!g_markup_parse_context_parse (context, buffer, length, error))
3366 if (!g_markup_parse_context_end_parse (context, error))
3369 parser->parsed_modules = g_list_concat (g_list_copy (ctx.modules),
3370 parser->parsed_modules);
3374 if (ctx.modules == NULL)
3376 /* An error occurred before we created a module, so we haven't
3377 * transferred ownership of these hash tables to the module.
3379 if (ctx.aliases != NULL)
3380 g_hash_table_destroy (ctx.aliases);
3381 if (ctx.disguised_structures != NULL)
3382 g_hash_table_destroy (ctx.disguised_structures);
3383 g_list_free (ctx.include_modules);
3386 g_markup_parse_context_free (context);
3392 * g_ir_parser_parse_file:
3393 * @parser: a #GIrParser
3394 * @filename: filename to parse
3395 * @error: return location for a #GError, or %NULL
3397 * Parse GIR XML file, and return a list of a a #GirModule for each
3398 * <namespace/> element within the file.
3400 * Returns: a newly allocated list of #GIrModule. The modules themselves
3401 * are owned by the #GIrParser and will be freed along with the parser.
3404 g_ir_parser_parse_file (GIrParser *parser,
3405 const gchar *filename,
3416 if (!g_str_has_suffix (filename, ".gir"))
3420 G_MARKUP_ERROR_INVALID_CONTENT,
3421 "Expected filename to end with '.gir'");
3425 g_debug ("[parsing] filename %s", filename);
3427 slash = g_strrstr (filename, "/");
3429 namespace = g_strdup (filename);
3431 namespace = g_strdup (slash+1);
3432 namespace[strlen(namespace)-4] = '\0';
3434 /* Remove version */
3435 dash = strstr (namespace, "-");
3439 if (!g_file_get_contents (filename, &buffer, &length, error))
3442 modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error);
3444 for (iter = modules; iter; iter = iter->next)
3446 post_filter ((GIrModule*)iter->data);