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,
74 typedef struct _ParseContext ParseContext;
81 ParseState prev_state;
84 GList *include_modules;
87 GHashTable *disguised_structures;
89 const char *namespace;
90 GIrModule *current_module;
92 GIrNode *current_typed;
95 GList *type_parameters;
98 #define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
100 static void start_element_handler (GMarkupParseContext *context,
101 const gchar *element_name,
102 const gchar **attribute_names,
103 const gchar **attribute_values,
106 static void end_element_handler (GMarkupParseContext *context,
107 const gchar *element_name,
110 static void text_handler (GMarkupParseContext *context,
115 static void cleanup (GMarkupParseContext *context,
119 static GMarkupParser markup_parser =
121 start_element_handler,
129 start_alias (GMarkupParseContext *context,
130 const gchar *element_name,
131 const gchar **attribute_names,
132 const gchar **attribute_values,
136 static const gchar *find_attribute (const gchar *name,
137 const gchar **attribute_names,
138 const gchar **attribute_values);
142 g_ir_parser_new (void)
144 GIrParser *parser = g_slice_new0 (GIrParser);
150 g_ir_parser_free (GIrParser *parser)
154 if (parser->includes)
155 g_strfreev (parser->includes);
157 for (l = parser->parsed_modules; l; l = l->next)
158 g_ir_module_free (l->data);
160 g_slice_free (GIrParser, parser);
164 g_ir_parser_set_includes (GIrParser *parser,
165 const gchar *const *includes)
167 if (parser->includes)
168 g_strfreev (parser->includes);
170 parser->includes = g_strdupv ((char **)includes);
174 firstpass_start_element_handler (GMarkupParseContext *context,
175 const gchar *element_name,
176 const gchar **attribute_names,
177 const gchar **attribute_values,
181 ParseContext *ctx = user_data;
183 if (strcmp (element_name, "alias") == 0)
185 start_alias (context, element_name, attribute_names, attribute_values,
188 else if (strcmp (element_name, "record") == 0)
191 const gchar *disguised;
193 name = find_attribute ("name", attribute_names, attribute_values);
194 disguised = find_attribute ("disguised", attribute_names, attribute_values);
196 if (disguised && strcmp (disguised, "1") == 0)
200 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
201 g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
207 firstpass_end_element_handler (GMarkupParseContext *context,
208 const gchar *element_name,
214 static GMarkupParser firstpass_parser =
216 firstpass_start_element_handler,
217 firstpass_end_element_handler,
224 locate_gir (GIrParser *parser,
228 const gchar *const *datadirs;
229 const gchar *const *dir;
233 datadirs = g_get_system_data_dirs ();
235 girname = g_strdup_printf ("%s-%s.gir", name, version);
237 if (parser->includes != NULL)
239 for (dir = (const gchar *const *)parser->includes; *dir; dir++)
241 path = g_build_filename (*dir, girname, NULL);
242 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
248 for (dir = datadirs; *dir; dir++)
250 path = g_build_filename (*dir, "gir-1.0", girname, NULL);
251 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
260 #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \
262 int line_number, char_number; \
263 g_markup_parse_context_get_position (context, &line_number, &char_number); \
264 g_set_error (error, \
266 G_MARKUP_ERROR_INVALID_CONTENT, \
267 "Line %d, character %d: The attribute '%s' on the element '%s' must be specified", \
268 line_number, char_number, attribute, element); \
272 backtrace_stderr (void)
274 #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
280 size = backtrace (array, 50);
281 strings = (char**) backtrace_symbols (array, size);
283 fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size);
285 for (i = 0; i < size; i++)
286 fprintf (stderr, "%s\n", strings[i]);
288 fprintf (stderr, "--- END BACKTRACE ---\n", size);
296 find_attribute (const gchar *name,
297 const gchar **attribute_names,
298 const gchar **attribute_values)
302 for (i = 0; attribute_names[i] != NULL; i++)
303 if (strcmp (attribute_names[i], name) == 0)
304 return attribute_values[i];
310 state_switch (ParseContext *ctx, ParseState newstate)
312 g_debug ("State: %d", newstate);
313 ctx->prev_state = ctx->state;
314 ctx->state = newstate;
318 pop_node (ParseContext *ctx)
320 g_assert (ctx->node_stack != 0);
322 GSList *top = ctx->node_stack;
323 GIrNode *node = top->data;
325 g_debug ("popping node %d %s", node->type, node->name);
326 ctx->node_stack = top->next;
327 g_slist_free_1 (top);
332 push_node (ParseContext *ctx, GIrNode *node)
334 g_debug ("pushing node %d %s", node->type, node->name);
335 ctx->node_stack = g_slist_prepend (ctx->node_stack, node);
338 static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
339 gboolean in_gobject);
347 static BasicTypeInfo basic_types[] = {
348 { "none", GI_TYPE_TAG_VOID, 0 },
349 { "any", GI_TYPE_TAG_VOID, 1 },
351 { "bool", GI_TYPE_TAG_BOOLEAN, 0 },
352 { "char", GI_TYPE_TAG_INT8, 0 },
353 { "int8", GI_TYPE_TAG_INT8, 0 },
354 { "uint8", GI_TYPE_TAG_UINT8, 0 },
355 { "int16", GI_TYPE_TAG_INT16, 0 },
356 { "uint16", GI_TYPE_TAG_UINT16, 0 },
357 { "int32", GI_TYPE_TAG_INT32, 0 },
358 { "uint32", GI_TYPE_TAG_UINT32, 0 },
359 { "int64", GI_TYPE_TAG_INT64, 0 },
360 { "uint64", GI_TYPE_TAG_UINT64, 0 },
361 { "int", GI_TYPE_TAG_INT, 0 },
362 { "uint", GI_TYPE_TAG_UINT, 0 },
363 { "long", GI_TYPE_TAG_LONG, 0 },
364 { "ulong", GI_TYPE_TAG_ULONG, 0 },
365 { "ssize_t", GI_TYPE_TAG_SSIZE, 0 },
366 { "ssize", GI_TYPE_TAG_SSIZE, 0 },
367 { "size_t", GI_TYPE_TAG_SIZE, 0 },
368 { "size", GI_TYPE_TAG_SIZE, 0 },
369 { "float", GI_TYPE_TAG_FLOAT, 0 },
370 { "double", GI_TYPE_TAG_DOUBLE, 0 },
371 { "time_t", GI_TYPE_TAG_TIME_T, 0 },
372 { "GType", GI_TYPE_TAG_GTYPE, 0 },
373 { "utf8", GI_TYPE_TAG_UTF8, 1 },
374 { "filename", GI_TYPE_TAG_FILENAME,1 },
377 static const BasicTypeInfo *
378 parse_basic (const char *str)
381 gint n_basic = G_N_ELEMENTS (basic_types);
383 for (i = 0; i < n_basic; i++)
385 if (g_str_has_prefix (str, basic_types[i].str))
386 return &(basic_types[i]);
392 parse_type_internal (const gchar *str, char **next, gboolean in_glib,
395 const BasicTypeInfo *basic;
397 char *temporary_type = NULL;
399 type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
401 type->unparsed = g_strdup (str);
403 /* See comment below on GLib.List handling */
404 if (in_gobject && strcmp (str, "Type") == 0)
406 temporary_type = g_strdup ("GLib.Type");
407 str = temporary_type;
410 basic = parse_basic (str);
413 type->is_basic = TRUE;
414 type->tag = basic->tag;
415 type->is_pointer = basic->pointer;
417 str += strlen(basic->str);
421 /* If we're inside GLib, handle "List" etc. by prefixing with
422 * "GLib." so the parsing code below doesn't have to get more
425 if (g_str_has_prefix (str, "List<") ||
426 strcmp (str, "List") == 0)
428 temporary_type = g_strdup_printf ("GLib.List%s", str + 4);
429 str = temporary_type;
431 else if (g_str_has_prefix (str, "SList<") ||
432 strcmp (str, "SList") == 0)
434 temporary_type = g_strdup_printf ("GLib.SList%s", str + 5);
435 str = temporary_type;
437 else if (g_str_has_prefix (str, "HashTable<") ||
438 strcmp (str, "HashTable") == 0)
440 temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9);
441 str = temporary_type;
443 else if (g_str_has_prefix (str, "Error<") ||
444 strcmp (str, "Error") == 0)
446 temporary_type = g_strdup_printf ("GLib.Error%s", str + 5);
447 str = temporary_type;
452 /* found a basic type */;
453 else if (g_str_has_prefix (str, "GLib.List") ||
454 g_str_has_prefix (str, "GLib.SList"))
456 str += strlen ("GLib.");
457 if (g_str_has_prefix (str, "List"))
459 type->tag = GI_TYPE_TAG_GLIST;
460 type->is_glist = TRUE;
461 type->is_pointer = TRUE;
462 str += strlen ("List");
466 type->tag = GI_TYPE_TAG_GSLIST;
467 type->is_gslist = TRUE;
468 type->is_pointer = TRUE;
469 str += strlen ("SList");
472 else if (g_str_has_prefix (str, "GLib.HashTable"))
474 str += strlen ("GLib.");
476 type->tag = GI_TYPE_TAG_GHASH;
477 type->is_ghashtable = TRUE;
478 type->is_pointer = TRUE;
479 str += strlen ("HashTable");
481 else if (g_str_has_prefix (str, "GLib.Error"))
483 str += strlen ("GLib.");
485 type->tag = GI_TYPE_TAG_ERROR;
486 type->is_error = TRUE;
487 type->is_pointer = TRUE;
488 str += strlen ("Error");
495 end = strchr (str, '>');
496 tmp = g_strndup (str, end - str);
497 type->errors = g_strsplit (tmp, ",", 0);
505 type->tag = GI_TYPE_TAG_INTERFACE;
506 type->is_interface = TRUE;
507 const char *start = str;
509 /* must be an interface type */
510 while (g_ascii_isalnum (*str) ||
517 type->interface = g_strndup (start, str - start);
522 g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR);
523 g_free (temporary_type);
527 g_ir_node_free ((GIrNode *)type);
528 g_free (temporary_type);
533 resolve_aliases (ParseContext *ctx, const gchar *type)
537 GSList *seen_values = NULL;
541 if (strchr (type, '.') == NULL)
543 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
552 seen_values = g_slist_prepend (seen_values, (char*)lookup);
553 while (g_hash_table_lookup_extended (ctx->current_module->aliases, lookup, &orig, &value))
555 g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
557 if (g_slist_find_custom (seen_values, lookup,
558 (GCompareFunc)strcmp) != NULL)
560 seen_values = g_slist_prepend (seen_values, (gchar*)lookup);
562 g_slist_free (seen_values);
564 if (lookup == prefixed)
573 is_disguised_structure (ParseContext *ctx, const gchar *type)
579 if (strchr (type, '.') == NULL)
581 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
590 result = g_hash_table_lookup (ctx->current_module->disguised_structures,
599 parse_type (ParseContext *ctx, const gchar *type)
602 const BasicTypeInfo *basic;
603 gboolean in_glib, in_gobject;
605 in_glib = strcmp (ctx->namespace, "GLib") == 0;
606 in_gobject = strcmp (ctx->namespace, "GObject") == 0;
608 /* Do not search aliases for basic types */
609 basic = parse_basic (type);
611 type = resolve_aliases (ctx, type);
613 node = parse_type_internal (type, NULL, in_glib, in_gobject);
615 g_debug ("Parsed type: %s => %d", type, node->tag);
617 g_critical ("Failed to parse type: '%s'", type);
623 start_glib_boxed (GMarkupParseContext *context,
624 const gchar *element_name,
625 const gchar **attribute_names,
626 const gchar **attribute_values,
631 const gchar *typename;
632 const gchar *typeinit;
633 const gchar *deprecated;
636 if (!(strcmp (element_name, "glib:boxed") == 0 &&
637 ctx->state == STATE_NAMESPACE))
640 name = find_attribute ("glib:name", attribute_names, attribute_values);
641 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
642 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
643 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
647 MISSING_ATTRIBUTE (context, error, element_name, "glib:name");
650 else if (typename == NULL)
652 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
655 else if (typeinit == NULL)
657 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
661 boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED);
663 ((GIrNode *)boxed)->name = g_strdup (name);
664 boxed->gtype_name = g_strdup (typename);
665 boxed->gtype_init = g_strdup (typeinit);
667 boxed->deprecated = TRUE;
669 boxed->deprecated = FALSE;
671 push_node (ctx, (GIrNode *)boxed);
672 ctx->current_module->entries =
673 g_list_append (ctx->current_module->entries, boxed);
675 state_switch (ctx, STATE_BOXED);
681 start_function (GMarkupParseContext *context,
682 const gchar *element_name,
683 const gchar **attribute_names,
684 const gchar **attribute_values,
690 const gchar *deprecated;
692 GIrNodeFunction *function;
693 gboolean found = FALSE;
697 case STATE_NAMESPACE:
698 found = (strcmp (element_name, "function") == 0 ||
699 strcmp (element_name, "callback") == 0);
702 found = strcmp (element_name, "function") == 0;
707 found = (found || strcmp (element_name, "constructor") == 0);
709 case STATE_INTERFACE:
711 strcmp (element_name, "method") == 0 ||
712 strcmp (element_name, "callback") == 0);
721 name = find_attribute ("name", attribute_names, attribute_values);
722 symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
723 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
724 throws = find_attribute ("throws", attribute_names, attribute_values);
728 MISSING_ATTRIBUTE (context, error, element_name, "name");
731 else if (strcmp (element_name, "callback") != 0 && symbol == NULL)
733 MISSING_ATTRIBUTE (context, error, element_name, "c:identifier");
737 function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION);
739 ((GIrNode *)function)->name = g_strdup (name);
740 function->symbol = g_strdup (symbol);
741 function->parameters = NULL;
743 function->deprecated = TRUE;
745 function->deprecated = FALSE;
747 if (strcmp (element_name, "method") == 0 ||
748 strcmp (element_name, "constructor") == 0)
750 function->is_method = TRUE;
752 if (strcmp (element_name, "constructor") == 0)
753 function->is_constructor = TRUE;
755 function->is_constructor = FALSE;
759 function->is_method = FALSE;
760 function->is_setter = FALSE;
761 function->is_getter = FALSE;
762 function->is_constructor = FALSE;
763 if (strcmp (element_name, "callback") == 0)
764 ((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
767 if (throws && strcmp (throws, "1") == 0)
768 function->throws = TRUE;
770 function->throws = FALSE;
772 if (ctx->node_stack == NULL)
774 ctx->current_module->entries =
775 g_list_append (ctx->current_module->entries, function);
778 switch (CURRENT_NODE (ctx)->type)
780 case G_IR_NODE_INTERFACE:
781 case G_IR_NODE_OBJECT:
783 GIrNodeInterface *iface;
785 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
786 iface->members = g_list_append (iface->members, function);
789 case G_IR_NODE_BOXED:
793 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
794 boxed->members = g_list_append (boxed->members, function);
797 case G_IR_NODE_STRUCT:
799 GIrNodeStruct *struct_;
801 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
802 struct_->members = g_list_append (struct_->members, function); }
804 case G_IR_NODE_UNION:
806 GIrNodeUnion *union_;
808 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
809 union_->members = g_list_append (union_->members, function);
813 g_assert_not_reached ();
816 push_node(ctx, (GIrNode *)function);
817 state_switch (ctx, STATE_FUNCTION);
823 parse_param_transfer (GIrNodeParam *param, const gchar *transfer)
825 if (transfer == NULL)
827 g_warning ("required attribute 'transfer-ownership' missing");
829 else if (strcmp (transfer, "none") == 0)
831 param->transfer = FALSE;
832 param->shallow_transfer = FALSE;
834 else if (strcmp (transfer, "container") == 0)
836 param->transfer = FALSE;
837 param->shallow_transfer = TRUE;
839 else if (strcmp (transfer, "full") == 0)
841 param->transfer = TRUE;
842 param->shallow_transfer = FALSE;
846 g_warning ("Unknown transfer-ownership value: %s", transfer);
851 start_parameter (GMarkupParseContext *context,
852 const gchar *element_name,
853 const gchar **attribute_names,
854 const gchar **attribute_values,
859 const gchar *direction;
862 const gchar *optional;
863 const gchar *allow_none;
864 const gchar *transfer;
866 const gchar *closure;
867 const gchar *destroy;
870 if (!(strcmp (element_name, "parameter") == 0 &&
871 ctx->state == STATE_FUNCTION_PARAMETERS))
874 name = find_attribute ("name", attribute_names, attribute_values);
875 direction = find_attribute ("direction", attribute_names, attribute_values);
876 retval = find_attribute ("retval", attribute_names, attribute_values);
877 dipper = find_attribute ("dipper", attribute_names, attribute_values);
878 optional = find_attribute ("optional", attribute_names, attribute_values);
879 allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
880 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
881 scope = find_attribute ("scope", attribute_names, attribute_values);
882 closure = find_attribute ("closure", attribute_names, attribute_values);
883 destroy = find_attribute ("destroy", attribute_names, attribute_values);
888 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
890 ctx->current_typed = (GIrNode*) param;
891 ctx->current_typed->name = g_strdup (name);
893 state_switch (ctx, STATE_FUNCTION_PARAMETER);
895 if (direction && strcmp (direction, "out") == 0)
900 else if (direction && strcmp (direction, "inout") == 0)
911 if (retval && strcmp (retval, "1") == 0)
912 param->retval = TRUE;
914 param->retval = FALSE;
916 if (dipper && strcmp (dipper, "1") == 0)
917 param->dipper = TRUE;
919 param->dipper = FALSE;
921 if (optional && strcmp (optional, "1") == 0)
922 param->optional = TRUE;
924 param->optional = FALSE;
926 if (allow_none && strcmp (allow_none, "1") == 0)
927 param->allow_none = TRUE;
929 param->allow_none = FALSE;
931 parse_param_transfer (param, transfer);
933 if (scope && strcmp (scope, "call") == 0)
934 param->scope = GI_SCOPE_TYPE_CALL;
935 else if (scope && strcmp (scope, "object") == 0)
936 param->scope = GI_SCOPE_TYPE_OBJECT;
937 else if (scope && strcmp (scope, "async") == 0)
938 param->scope = GI_SCOPE_TYPE_ASYNC;
939 else if (scope && strcmp (scope, "notified") == 0)
940 param->scope = GI_SCOPE_TYPE_NOTIFIED;
942 param->scope = GI_SCOPE_TYPE_INVALID;
944 param->closure = closure ? atoi (closure) : -1;
945 param->destroy = destroy ? atoi (destroy) : -1;
947 ((GIrNode *)param)->name = g_strdup (name);
949 switch (CURRENT_NODE (ctx)->type)
951 case G_IR_NODE_FUNCTION:
952 case G_IR_NODE_CALLBACK:
954 GIrNodeFunction *func;
956 func = (GIrNodeFunction *)CURRENT_NODE (ctx);
957 func->parameters = g_list_append (func->parameters, param);
960 case G_IR_NODE_SIGNAL:
962 GIrNodeSignal *signal;
964 signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
965 signal->parameters = g_list_append (signal->parameters, param);
968 case G_IR_NODE_VFUNC:
972 vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
973 vfunc->parameters = g_list_append (vfunc->parameters, param);
977 g_assert_not_reached ();
984 start_field (GMarkupParseContext *context,
985 const gchar *element_name,
986 const gchar **attribute_names,
987 const gchar **attribute_values,
992 const gchar *readable;
993 const gchar *writable;
1004 case STATE_INTERFACE:
1010 if (strcmp (element_name, "field") != 0)
1013 name = find_attribute ("name", attribute_names, attribute_values);
1014 readable = find_attribute ("readable", attribute_names, attribute_values);
1015 writable = find_attribute ("writable", attribute_names, attribute_values);
1016 bits = find_attribute ("bits", attribute_names, attribute_values);
1017 branch = find_attribute ("branch", attribute_names, attribute_values);
1021 MISSING_ATTRIBUTE (context, error, element_name, "name");
1025 field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD);
1026 ctx->current_typed = (GIrNode*) field;
1027 ((GIrNode *)field)->name = g_strdup (name);
1028 /* Fields are assumed to be read-only.
1029 * (see also girwriter.py and generate.c)
1031 field->readable = readable == NULL || strcmp (readable, "0") == 0;
1032 field->writable = writable != NULL && strcmp (writable, "1") == 0;
1035 field->bits = atoi (bits);
1039 switch (CURRENT_NODE (ctx)->type)
1041 case G_IR_NODE_OBJECT:
1043 GIrNodeInterface *iface;
1045 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1046 iface->members = g_list_append (iface->members, field);
1047 state_switch (ctx, STATE_CLASS_FIELD);
1050 case G_IR_NODE_INTERFACE:
1052 GIrNodeInterface *iface;
1054 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1055 iface->members = g_list_append (iface->members, field);
1056 state_switch (ctx, STATE_INTERFACE_FIELD);
1059 case G_IR_NODE_BOXED:
1061 GIrNodeBoxed *boxed;
1063 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
1064 boxed->members = g_list_append (boxed->members, field);
1065 state_switch (ctx, STATE_BOXED_FIELD);
1068 case G_IR_NODE_STRUCT:
1070 GIrNodeStruct *struct_;
1072 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
1073 struct_->members = g_list_append (struct_->members, field);
1074 state_switch (ctx, STATE_STRUCT_FIELD);
1077 case G_IR_NODE_UNION:
1079 GIrNodeUnion *union_;
1081 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
1082 union_->members = g_list_append (union_->members, field);
1085 GIrNodeConstant *constant;
1087 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1088 ((GIrNode *)constant)->name = g_strdup (name);
1089 constant->value = g_strdup (branch);
1090 constant->type = union_->discriminator_type;
1091 constant->deprecated = FALSE;
1093 union_->discriminators = g_list_append (union_->discriminators, constant);
1095 state_switch (ctx, STATE_UNION_FIELD);
1099 g_assert_not_reached ();
1106 start_alias (GMarkupParseContext *context,
1107 const gchar *element_name,
1108 const gchar **attribute_names,
1109 const gchar **attribute_values,
1114 const gchar *target;
1118 name = find_attribute ("name", attribute_names, attribute_values);
1121 MISSING_ATTRIBUTE (context, error, element_name, "name");
1125 target = find_attribute ("target", attribute_names, attribute_values);
1128 MISSING_ATTRIBUTE (context, error, element_name, "target");
1132 value = g_strdup (target);
1133 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
1134 if (!strchr (target, '.'))
1136 const BasicTypeInfo *basic = parse_basic (target);
1140 /* For non-basic types, re-qualify the interface */
1141 value = g_strdup_printf ("%s.%s", ctx->namespace, target);
1144 g_hash_table_replace (ctx->aliases, key, value);
1150 start_enum (GMarkupParseContext *context,
1151 const gchar *element_name,
1152 const gchar **attribute_names,
1153 const gchar **attribute_values,
1157 if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
1158 (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))
1161 const gchar *typename;
1162 const gchar *typeinit;
1163 const gchar *deprecated;
1165 name = find_attribute ("name", attribute_names, attribute_values);
1166 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1167 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1168 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1171 MISSING_ATTRIBUTE (context, error, element_name, "name");
1176 if (strcmp (element_name, "enumeration") == 0)
1177 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM);
1179 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS);
1180 ((GIrNode *)enum_)->name = g_strdup (name);
1181 enum_->gtype_name = g_strdup (typename);
1182 enum_->gtype_init = g_strdup (typeinit);
1184 enum_->deprecated = TRUE;
1186 enum_->deprecated = FALSE;
1188 push_node (ctx, (GIrNode *) enum_);
1189 ctx->current_module->entries =
1190 g_list_append (ctx->current_module->entries, enum_);
1192 state_switch (ctx, STATE_ENUM);
1201 start_property (GMarkupParseContext *context,
1202 const gchar *element_name,
1203 const gchar **attribute_names,
1204 const gchar **attribute_values,
1208 if (strcmp (element_name, "property") == 0 &&
1209 (ctx->state == STATE_CLASS ||
1210 ctx->state == STATE_INTERFACE))
1213 const gchar *readable;
1214 const gchar *writable;
1215 const gchar *construct;
1216 const gchar *construct_only;
1218 name = find_attribute ("name", attribute_names, attribute_values);
1219 readable = find_attribute ("readable", attribute_names, attribute_values);
1220 writable = find_attribute ("writable", attribute_names, attribute_values);
1221 construct = find_attribute ("construct", attribute_names, attribute_values);
1222 construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
1225 MISSING_ATTRIBUTE (context, error, element_name, "name");
1228 GIrNodeProperty *property;
1229 GIrNodeInterface *iface;
1231 property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
1232 ctx->current_typed = (GIrNode*) property;
1234 ((GIrNode *)property)->name = g_strdup (name);
1236 /* Assume properties are readable */
1237 if (readable == NULL || strcmp (readable, "1") == 0)
1238 property->readable = TRUE;
1240 property->readable = FALSE;
1241 if (writable && strcmp (writable, "1") == 0)
1242 property->writable = TRUE;
1244 property->writable = FALSE;
1245 if (construct && strcmp (construct, "1") == 0)
1246 property->construct = TRUE;
1248 property->construct = FALSE;
1249 if (construct_only && strcmp (construct_only, "1") == 0)
1250 property->construct_only = TRUE;
1252 property->construct_only = FALSE;
1254 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1255 iface->members = g_list_append (iface->members, property);
1257 if (ctx->state == STATE_CLASS)
1258 state_switch (ctx, STATE_CLASS_PROPERTY);
1259 else if (ctx->state == STATE_INTERFACE)
1260 state_switch (ctx, STATE_INTERFACE_PROPERTY);
1262 g_assert_not_reached ();
1271 parse_value (const gchar *str)
1275 /* FIXME just a quick hack */
1276 shift_op = strstr (str, "<<");
1282 base = strtol (str, NULL, 10);
1283 shift = strtol (shift_op + 3, NULL, 10);
1285 return base << shift;
1288 return strtol (str, NULL, 10);
1294 start_member (GMarkupParseContext *context,
1295 const gchar *element_name,
1296 const gchar **attribute_names,
1297 const gchar **attribute_values,
1301 if (strcmp (element_name, "member") == 0 &&
1302 ctx->state == STATE_ENUM)
1306 const gchar *deprecated;
1308 name = find_attribute ("name", attribute_names, attribute_values);
1309 value = find_attribute ("value", attribute_names, attribute_values);
1310 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1313 MISSING_ATTRIBUTE (context, error, element_name, "name");
1317 GIrNodeValue *value_;
1319 value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
1321 ((GIrNode *)value_)->name = g_strdup (name);
1323 value_->value = parse_value (value);
1326 value_->deprecated = TRUE;
1328 value_->deprecated = FALSE;
1330 enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx);
1331 enum_->values = g_list_append (enum_->values, value_);
1340 start_constant (GMarkupParseContext *context,
1341 const gchar *element_name,
1342 const gchar **attribute_names,
1343 const gchar **attribute_values,
1347 if (strcmp (element_name, "constant") == 0 &&
1348 (ctx->state == STATE_NAMESPACE ||
1349 ctx->state == STATE_CLASS ||
1350 ctx->state == STATE_INTERFACE))
1354 const gchar *deprecated;
1356 name = find_attribute ("name", attribute_names, attribute_values);
1357 value = find_attribute ("value", attribute_names, attribute_values);
1358 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1361 MISSING_ATTRIBUTE (context, error, element_name, "name");
1362 else if (value == NULL)
1363 MISSING_ATTRIBUTE (context, error, element_name, "value");
1366 GIrNodeConstant *constant;
1368 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1370 ((GIrNode *)constant)->name = g_strdup (name);
1371 constant->value = g_strdup (value);
1373 ctx->current_typed = (GIrNode*) constant;
1376 constant->deprecated = TRUE;
1378 constant->deprecated = FALSE;
1380 if (ctx->state == STATE_NAMESPACE)
1382 push_node (ctx, (GIrNode *) constant);
1383 ctx->current_module->entries =
1384 g_list_append (ctx->current_module->entries, constant);
1388 GIrNodeInterface *iface;
1390 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1391 iface->members = g_list_append (iface->members, constant);
1396 case STATE_NAMESPACE:
1397 state_switch (ctx, STATE_NAMESPACE_CONSTANT);
1400 state_switch (ctx, STATE_CLASS_CONSTANT);
1402 case STATE_INTERFACE:
1403 state_switch (ctx, STATE_INTERFACE_CONSTANT);
1406 g_assert_not_reached ();
1417 start_errordomain (GMarkupParseContext *context,
1418 const gchar *element_name,
1419 const gchar **attribute_names,
1420 const gchar **attribute_values,
1424 if (strcmp (element_name, "errordomain") == 0 &&
1425 ctx->state == STATE_NAMESPACE)
1428 const gchar *getquark;
1430 const gchar *deprecated;
1432 name = find_attribute ("name", attribute_names, attribute_values);
1433 getquark = find_attribute ("get-quark", attribute_names, attribute_values);
1434 codes = find_attribute ("codes", attribute_names, attribute_values);
1435 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1438 MISSING_ATTRIBUTE (context, error, element_name, "name");
1439 else if (getquark == NULL)
1440 MISSING_ATTRIBUTE (context, error, element_name, "getquark");
1441 else if (codes == NULL)
1442 MISSING_ATTRIBUTE (context, error, element_name, "codes");
1445 GIrNodeErrorDomain *domain;
1447 domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
1449 ((GIrNode *)domain)->name = g_strdup (name);
1450 domain->getquark = g_strdup (getquark);
1451 domain->codes = g_strdup (codes);
1454 domain->deprecated = TRUE;
1456 domain->deprecated = FALSE;
1458 push_node (ctx, (GIrNode *) domain);
1459 ctx->current_module->entries =
1460 g_list_append (ctx->current_module->entries, domain);
1462 state_switch (ctx, STATE_ERRORDOMAIN);
1471 start_interface (GMarkupParseContext *context,
1472 const gchar *element_name,
1473 const gchar **attribute_names,
1474 const gchar **attribute_values,
1478 if (strcmp (element_name, "interface") == 0 &&
1479 ctx->state == STATE_NAMESPACE)
1482 const gchar *typename;
1483 const gchar *typeinit;
1484 const gchar *deprecated;
1486 name = find_attribute ("name", attribute_names, attribute_values);
1487 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1488 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1489 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1492 MISSING_ATTRIBUTE (context, error, element_name, "name");
1493 else if (typename == NULL)
1494 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1495 else if (typeinit == NULL)
1496 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1499 GIrNodeInterface *iface;
1501 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE);
1502 ((GIrNode *)iface)->name = g_strdup (name);
1503 iface->gtype_name = g_strdup (typename);
1504 iface->gtype_init = g_strdup (typeinit);
1506 iface->deprecated = TRUE;
1508 iface->deprecated = FALSE;
1510 push_node (ctx, (GIrNode *) iface);
1511 ctx->current_module->entries =
1512 g_list_append (ctx->current_module->entries, iface);
1514 state_switch (ctx, STATE_INTERFACE);
1524 start_class (GMarkupParseContext *context,
1525 const gchar *element_name,
1526 const gchar **attribute_names,
1527 const gchar **attribute_values,
1531 if (strcmp (element_name, "class") == 0 &&
1532 ctx->state == STATE_NAMESPACE)
1535 const gchar *parent;
1536 const gchar *class_struct;
1537 const gchar *typename;
1538 const gchar *typeinit;
1539 const gchar *deprecated;
1540 const gchar *abstract;
1542 name = find_attribute ("name", attribute_names, attribute_values);
1543 parent = find_attribute ("parent", attribute_names, attribute_values);
1544 class_struct = find_attribute ("glib:class-struct", attribute_names, attribute_values);
1545 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1546 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1547 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1548 abstract = find_attribute ("abstract", attribute_names, attribute_values);
1551 MISSING_ATTRIBUTE (context, error, element_name, "name");
1552 else if (typename == NULL)
1553 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1554 else if (typeinit == NULL && strcmp (typename, "GObject"))
1555 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1558 GIrNodeInterface *iface;
1560 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT);
1561 ((GIrNode *)iface)->name = g_strdup (name);
1562 iface->gtype_name = g_strdup (typename);
1563 iface->gtype_init = g_strdup (typeinit);
1564 iface->parent = g_strdup (parent);
1565 iface->class_struct = g_strdup (class_struct);
1567 iface->deprecated = TRUE;
1569 iface->deprecated = FALSE;
1571 iface->abstract = abstract && strcmp (abstract, "1") == 0;
1573 push_node (ctx, (GIrNode *) iface);
1574 ctx->current_module->entries =
1575 g_list_append (ctx->current_module->entries, iface);
1577 state_switch (ctx, STATE_CLASS);
1586 start_type (GMarkupParseContext *context,
1587 const gchar *element_name,
1588 const gchar **attribute_names,
1589 const gchar **attribute_values,
1596 gboolean is_varargs;
1597 GIrNodeType *typenode;
1599 is_array = strcmp (element_name, "array") == 0;
1600 is_varargs = strcmp (element_name, "varargs") == 0;
1602 if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
1605 if (ctx->state == STATE_TYPE)
1608 ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters);
1609 ctx->type_parameters = NULL;
1611 else if (ctx->state == STATE_FUNCTION_PARAMETER ||
1612 ctx->state == STATE_FUNCTION_RETURN ||
1613 ctx->state == STATE_STRUCT_FIELD ||
1614 ctx->state == STATE_UNION_FIELD ||
1615 ctx->state == STATE_CLASS_PROPERTY ||
1616 ctx->state == STATE_CLASS_FIELD ||
1617 ctx->state == STATE_INTERFACE_FIELD ||
1618 ctx->state == STATE_INTERFACE_PROPERTY ||
1619 ctx->state == STATE_BOXED_FIELD ||
1620 ctx->state == STATE_NAMESPACE_CONSTANT ||
1621 ctx->state == STATE_CLASS_CONSTANT ||
1622 ctx->state == STATE_INTERFACE_CONSTANT
1625 state_switch (ctx, STATE_TYPE);
1626 ctx->type_depth = 1;
1629 switch (CURRENT_NODE (ctx)->type)
1631 case G_IR_NODE_FUNCTION:
1632 case G_IR_NODE_CALLBACK:
1634 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1635 func->is_varargs = TRUE;
1638 case G_IR_NODE_VFUNC:
1640 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1641 vfunc->is_varargs = TRUE;
1644 /* list others individually rather than with default: so that compiler
1645 * warns if new node types are added without adding them to the switch
1647 case G_IR_NODE_INVALID:
1648 case G_IR_NODE_ENUM:
1649 case G_IR_NODE_FLAGS:
1650 case G_IR_NODE_CONSTANT:
1651 case G_IR_NODE_ERROR_DOMAIN:
1652 case G_IR_NODE_PARAM:
1653 case G_IR_NODE_TYPE:
1654 case G_IR_NODE_PROPERTY:
1655 case G_IR_NODE_SIGNAL:
1656 case G_IR_NODE_VALUE:
1657 case G_IR_NODE_FIELD:
1658 case G_IR_NODE_XREF:
1659 case G_IR_NODE_STRUCT:
1660 case G_IR_NODE_BOXED:
1661 case G_IR_NODE_OBJECT:
1662 case G_IR_NODE_INTERFACE:
1663 case G_IR_NODE_UNION:
1664 g_assert_not_reached ();
1668 ctx->type_stack = NULL;
1669 ctx->type_parameters = NULL;
1672 if (!ctx->current_typed)
1676 G_MARKUP_ERROR_INVALID_CONTENT,
1677 "The element <type> is invalid here");
1690 typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
1692 typenode->tag = GI_TYPE_TAG_ARRAY;
1693 typenode->is_pointer = TRUE;
1694 typenode->is_array = TRUE;
1696 zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
1697 len = find_attribute ("length", attribute_names, attribute_values);
1698 size = find_attribute ("fixed-size", attribute_names, attribute_values);
1700 typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0);
1701 typenode->has_length = len != NULL;
1702 typenode->length = typenode->has_length ? atoi (len) : -1;
1704 typenode->has_size = size != NULL;
1705 typenode->size = typenode->has_size ? atoi (size) : -1;
1710 name = find_attribute ("name", attribute_names, attribute_values);
1713 MISSING_ATTRIBUTE (context, error, element_name, "name");
1716 ctype = find_attribute ("c:type", attribute_names, attribute_values);
1719 const char *cp = ctype + strlen(ctype) - 1;
1720 while (cp > ctype && *cp-- == '*')
1724 if (ctx->current_typed->type == G_IR_NODE_PARAM &&
1725 ((GIrNodeParam *)ctx->current_typed)->out &&
1729 typenode = parse_type (ctx, name);
1731 /* A 'disguised' structure is one where the c:type is a typedef that
1732 * doesn't look like a pointer, but is internally.
1734 if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
1735 is_disguised_structure (ctx, typenode->interface))
1738 if (pointer_depth > 0)
1739 typenode->is_pointer = TRUE;
1742 ctx->type_parameters = g_list_append (ctx->type_parameters, typenode);
1748 end_type_top (ParseContext *ctx)
1750 GIrNodeType *typenode;
1752 if (!ctx->type_parameters)
1755 typenode = (GIrNodeType*)ctx->type_parameters->data;
1757 /* Default to pointer for unspecified containers */
1758 if (typenode->tag == GI_TYPE_TAG_ARRAY ||
1759 typenode->tag == GI_TYPE_TAG_GLIST ||
1760 typenode->tag == GI_TYPE_TAG_GSLIST)
1762 if (typenode->parameter_type1 == NULL)
1763 typenode->parameter_type1 = parse_type (ctx, "any");
1765 else if (typenode->tag == GI_TYPE_TAG_GHASH)
1767 if (typenode->parameter_type1 == NULL)
1769 typenode->parameter_type1 = parse_type (ctx, "any");
1770 typenode->parameter_type2 = parse_type (ctx, "any");
1774 switch (ctx->current_typed->type)
1776 case G_IR_NODE_PARAM:
1778 GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed;
1779 param->type = typenode;
1782 case G_IR_NODE_FIELD:
1784 GIrNodeField *field = (GIrNodeField *)ctx->current_typed;
1785 field->type = typenode;
1788 case G_IR_NODE_PROPERTY:
1790 GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed;
1791 property->type = typenode;
1794 case G_IR_NODE_CONSTANT:
1796 GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed;
1797 constant->type = typenode;
1801 g_printerr("current node is %d\n", CURRENT_NODE (ctx)->type);
1802 g_assert_not_reached ();
1804 g_list_free (ctx->type_parameters);
1807 ctx->type_depth = 0;
1808 ctx->type_parameters = NULL;
1809 ctx->current_typed = NULL;
1813 end_type_recurse (ParseContext *ctx)
1815 GIrNodeType *parent;
1816 GIrNodeType *param = NULL;
1818 parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data;
1819 if (ctx->type_parameters)
1820 param = (GIrNodeType *) ctx->type_parameters->data;
1822 if (parent->tag == GI_TYPE_TAG_ARRAY ||
1823 parent->tag == GI_TYPE_TAG_GLIST ||
1824 parent->tag == GI_TYPE_TAG_GSLIST)
1826 g_assert (param != NULL);
1828 if (parent->parameter_type1 == NULL)
1829 parent->parameter_type1 = param;
1831 g_assert_not_reached ();
1833 else if (parent->tag == GI_TYPE_TAG_GHASH)
1835 g_assert (param != NULL);
1837 if (parent->parameter_type1 == NULL)
1838 parent->parameter_type1 = param;
1839 else if (parent->parameter_type2 == NULL)
1840 parent->parameter_type2 = param;
1842 g_assert_not_reached ();
1844 g_list_free (ctx->type_parameters);
1845 ctx->type_parameters = (GList *)ctx->type_stack->data;
1846 ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
1850 end_type (ParseContext *ctx)
1852 if (ctx->type_depth == 1)
1855 state_switch (ctx, ctx->prev_state);
1859 end_type_recurse (ctx);
1865 start_return_value (GMarkupParseContext *context,
1866 const gchar *element_name,
1867 const gchar **attribute_names,
1868 const gchar **attribute_values,
1872 if (strcmp (element_name, "return-value") == 0 &&
1873 ctx->state == STATE_FUNCTION)
1875 GIrNodeParam *param;
1876 const gchar *transfer;
1878 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
1881 param->retval = TRUE;
1883 ctx->current_typed = (GIrNode*) param;
1885 state_switch (ctx, STATE_FUNCTION_RETURN);
1887 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1888 parse_param_transfer (param, transfer);
1890 switch (CURRENT_NODE (ctx)->type)
1892 case G_IR_NODE_FUNCTION:
1893 case G_IR_NODE_CALLBACK:
1895 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1896 func->result = param;
1899 case G_IR_NODE_SIGNAL:
1901 GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
1902 signal->result = param;
1905 case G_IR_NODE_VFUNC:
1907 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1908 vfunc->result = param;
1912 g_assert_not_reached ();
1922 start_implements (GMarkupParseContext *context,
1923 const gchar *element_name,
1924 const gchar **attribute_names,
1925 const gchar **attribute_values,
1929 GIrNodeInterface *iface;
1932 if (strcmp (element_name, "implements") != 0 ||
1933 !(ctx->state == STATE_CLASS))
1936 state_switch (ctx, STATE_IMPLEMENTS);
1938 name = find_attribute ("name", attribute_names, attribute_values);
1941 MISSING_ATTRIBUTE (context, error, element_name, "name");
1945 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1946 iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
1952 start_glib_signal (GMarkupParseContext *context,
1953 const gchar *element_name,
1954 const gchar **attribute_names,
1955 const gchar **attribute_values,
1959 if (strcmp (element_name, "glib:signal") == 0 &&
1960 (ctx->state == STATE_CLASS ||
1961 ctx->state == STATE_INTERFACE))
1965 const gchar *no_recurse;
1966 const gchar *detailed;
1967 const gchar *action;
1968 const gchar *no_hooks;
1969 const gchar *has_class_closure;
1971 name = find_attribute ("name", attribute_names, attribute_values);
1972 when = find_attribute ("when", attribute_names, attribute_values);
1973 no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values);
1974 detailed = find_attribute ("detailed", attribute_names, attribute_values);
1975 action = find_attribute ("action", attribute_names, attribute_values);
1976 no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values);
1977 has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values);
1980 MISSING_ATTRIBUTE (context, error, element_name, "name");
1983 GIrNodeInterface *iface;
1984 GIrNodeSignal *signal;
1986 signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
1988 ((GIrNode *)signal)->name = g_strdup (name);
1990 signal->run_first = FALSE;
1991 signal->run_last = FALSE;
1992 signal->run_cleanup = FALSE;
1993 if (when == NULL || strcmp (when, "LAST") == 0)
1994 signal->run_last = TRUE;
1995 else if (strcmp (when, "FIRST") == 0)
1996 signal->run_first = TRUE;
1998 signal->run_cleanup = TRUE;
2000 if (no_recurse && strcmp (no_recurse, "1") == 0)
2001 signal->no_recurse = TRUE;
2003 signal->no_recurse = FALSE;
2004 if (detailed && strcmp (detailed, "1") == 0)
2005 signal->detailed = TRUE;
2007 signal->detailed = FALSE;
2008 if (action && strcmp (action, "1") == 0)
2009 signal->action = TRUE;
2011 signal->action = FALSE;
2012 if (no_hooks && strcmp (no_hooks, "1") == 0)
2013 signal->no_hooks = TRUE;
2015 signal->no_hooks = FALSE;
2016 if (has_class_closure && strcmp (has_class_closure, "1") == 0)
2017 signal->has_class_closure = TRUE;
2019 signal->has_class_closure = FALSE;
2021 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2022 iface->members = g_list_append (iface->members, signal);
2024 push_node (ctx, (GIrNode *)signal);
2025 state_switch (ctx, STATE_FUNCTION);
2034 start_vfunc (GMarkupParseContext *context,
2035 const gchar *element_name,
2036 const gchar **attribute_names,
2037 const gchar **attribute_values,
2041 if (strcmp (element_name, "vfunc") == 0 &&
2042 (ctx->state == STATE_CLASS ||
2043 ctx->state == STATE_INTERFACE))
2046 const gchar *must_chain_up;
2047 const gchar *override;
2048 const gchar *is_class_closure;
2049 const gchar *offset;
2051 name = find_attribute ("name", attribute_names, attribute_values);
2052 must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values);
2053 override = find_attribute ("override", attribute_names, attribute_values);
2054 is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values);
2055 offset = find_attribute ("offset", attribute_names, attribute_values);
2058 MISSING_ATTRIBUTE (context, error, element_name, "name");
2061 GIrNodeInterface *iface;
2062 GIrNodeVFunc *vfunc;
2064 vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
2066 ((GIrNode *)vfunc)->name = g_strdup (name);
2068 if (must_chain_up && strcmp (must_chain_up, "1") == 0)
2069 vfunc->must_chain_up = TRUE;
2071 vfunc->must_chain_up = FALSE;
2073 if (override && strcmp (override, "always") == 0)
2075 vfunc->must_be_implemented = TRUE;
2076 vfunc->must_not_be_implemented = FALSE;
2078 else if (override && strcmp (override, "never") == 0)
2080 vfunc->must_be_implemented = FALSE;
2081 vfunc->must_not_be_implemented = TRUE;
2085 vfunc->must_be_implemented = FALSE;
2086 vfunc->must_not_be_implemented = FALSE;
2089 if (is_class_closure && strcmp (is_class_closure, "1") == 0)
2090 vfunc->is_class_closure = TRUE;
2092 vfunc->is_class_closure = FALSE;
2095 vfunc->offset = atoi (offset);
2099 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2100 iface->members = g_list_append (iface->members, vfunc);
2102 push_node (ctx, (GIrNode *)vfunc);
2103 state_switch (ctx, STATE_FUNCTION);
2113 start_struct (GMarkupParseContext *context,
2114 const gchar *element_name,
2115 const gchar **attribute_names,
2116 const gchar **attribute_values,
2120 if (strcmp (element_name, "record") == 0 &&
2121 (ctx->state == STATE_NAMESPACE ||
2122 ctx->state == STATE_UNION ||
2123 ctx->state == STATE_STRUCT ||
2124 ctx->state == STATE_CLASS))
2127 const gchar *deprecated;
2128 const gchar *disguised;
2129 const gchar *gtype_name;
2130 const gchar *gtype_init;
2131 const gchar *gclass_struct;
2132 GIrNodeStruct *struct_;
2134 name = find_attribute ("name", attribute_names, attribute_values);
2135 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2136 disguised = find_attribute ("disguised", attribute_names, attribute_values);
2137 gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
2138 gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
2139 gclass_struct = find_attribute ("glib:is-class-struct-for", attribute_names, attribute_values);
2141 if (name == NULL && ctx->node_stack == NULL)
2143 MISSING_ATTRIBUTE (context, error, element_name, "name");
2146 if ((gtype_name == NULL && gtype_init != NULL))
2148 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
2151 if ((gtype_name != NULL && gtype_init == NULL))
2153 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
2157 struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
2159 ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
2161 struct_->deprecated = TRUE;
2163 struct_->deprecated = FALSE;
2165 if (disguised && strcmp (disguised, "1") == 0)
2166 struct_->disguised = TRUE;
2168 struct_->is_gclass_struct = gclass_struct != NULL;
2170 struct_->gtype_name = g_strdup (gtype_name);
2171 struct_->gtype_init = g_strdup (gtype_init);
2173 if (ctx->node_stack == NULL)
2174 ctx->current_module->entries =
2175 g_list_append (ctx->current_module->entries, struct_);
2176 push_node (ctx, (GIrNode *)struct_);
2178 state_switch (ctx, STATE_STRUCT);
2186 start_union (GMarkupParseContext *context,
2187 const gchar *element_name,
2188 const gchar **attribute_names,
2189 const gchar **attribute_values,
2193 if (strcmp (element_name, "union") == 0 &&
2194 (ctx->state == STATE_NAMESPACE ||
2195 ctx->state == STATE_UNION ||
2196 ctx->state == STATE_STRUCT ||
2197 ctx->state == STATE_CLASS))
2200 const gchar *deprecated;
2201 const gchar *typename;
2202 const gchar *typeinit;
2204 name = find_attribute ("name", attribute_names, attribute_values);
2205 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2206 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
2207 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
2209 if (name == NULL && ctx->node_stack == NULL)
2210 MISSING_ATTRIBUTE (context, error, element_name, "name");
2213 GIrNodeUnion *union_;
2215 union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
2217 ((GIrNode *)union_)->name = g_strdup (name ? name : "");
2218 union_->gtype_name = g_strdup (typename);
2219 union_->gtype_init = g_strdup (typeinit);
2221 union_->deprecated = TRUE;
2223 union_->deprecated = FALSE;
2225 if (ctx->node_stack == NULL)
2226 ctx->current_module->entries =
2227 g_list_append (ctx->current_module->entries, union_);
2228 push_node (ctx, (GIrNode *)union_);
2230 state_switch (ctx, STATE_UNION);
2238 start_discriminator (GMarkupParseContext *context,
2239 const gchar *element_name,
2240 const gchar **attribute_names,
2241 const gchar **attribute_values,
2245 if (strcmp (element_name, "discriminator") == 0 &&
2246 ctx->state == STATE_UNION)
2249 const gchar *offset;
2251 type = find_attribute ("type", attribute_names, attribute_values);
2252 offset = find_attribute ("offset", attribute_names, attribute_values);
2254 MISSING_ATTRIBUTE (context, error, element_name, "type");
2255 else if (offset == NULL)
2256 MISSING_ATTRIBUTE (context, error, element_name, "offset");
2258 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type
2259 = parse_type (ctx, type);
2260 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset
2271 parse_include (GMarkupParseContext *context,
2274 const char *version,
2280 gboolean success = FALSE;
2284 for (l = ctx->parser->parsed_modules; l; l = l->next)
2286 GIrModule *m = l->data;
2288 if (strcmp (m->name, name) == 0)
2290 if (strcmp (m->version, version) == 0)
2292 ctx->include_modules = g_list_prepend (ctx->include_modules, m);
2300 G_MARKUP_ERROR_INVALID_CONTENT,
2301 "Module '%s' imported with conflicting versions '%s' and '%s'",
2302 name, m->version, version);
2308 girpath = locate_gir (ctx->parser, name, version);
2310 if (girpath == NULL)
2314 G_MARKUP_ERROR_INVALID_CONTENT,
2315 "Could not find GIR file '%s.gir'; check XDG_DATA_DIRS or use --includedir",
2320 g_debug ("Parsing include %s", girpath);
2322 if (!g_file_get_contents (girpath, &buffer, &length, error))
2329 modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error);
2330 success = error != NULL;
2332 ctx->include_modules = g_list_concat (ctx->include_modules,
2340 extern GLogLevelFlags logged_levels;
2343 start_element_handler (GMarkupParseContext *context,
2344 const gchar *element_name,
2345 const gchar **attribute_names,
2346 const gchar **attribute_values,
2350 ParseContext *ctx = user_data;
2351 gint line_number, char_number;
2353 if (logged_levels & G_LOG_LEVEL_DEBUG)
2355 GString *tags = g_string_new ("");
2357 for (i = 0; attribute_names[i]; i++)
2358 g_string_append_printf (tags, "%s=\"%s\" ",
2360 attribute_values[i]);
2364 g_string_insert_c (tags, 0, ' ');
2365 g_string_truncate (tags, tags->len - 1);
2367 g_debug ("<%s%s>", element_name, tags->str);
2368 g_string_free (tags, TRUE);
2371 switch (element_name[0])
2374 if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0)
2376 state_switch (ctx, STATE_ALIAS);
2379 if (start_type (context, element_name,
2380 attribute_names, attribute_values,
2385 if (start_enum (context, element_name,
2386 attribute_names, attribute_values,
2391 if (start_function (context, element_name,
2392 attribute_names, attribute_values,
2395 else if (start_constant (context, element_name,
2396 attribute_names, attribute_values,
2399 else if (start_class (context, element_name,
2400 attribute_names, attribute_values,
2406 if (start_discriminator (context, element_name,
2407 attribute_names, attribute_values,
2413 if (start_enum (context, element_name,
2414 attribute_names, attribute_values,
2417 else if (start_errordomain (context, element_name,
2418 attribute_names, attribute_values,
2424 if (start_function (context, element_name,
2425 attribute_names, attribute_values,
2428 else if (start_field (context, element_name,
2429 attribute_names, attribute_values,
2435 if (start_glib_boxed (context, element_name,
2436 attribute_names, attribute_values,
2439 else if (start_glib_signal (context, element_name,
2440 attribute_names, attribute_values,
2446 if (strcmp (element_name, "include") == 0 &&
2447 ctx->state == STATE_REPOSITORY)
2450 const gchar *version;
2452 name = find_attribute ("name", attribute_names, attribute_values);
2453 version = find_attribute ("version", attribute_names, attribute_values);
2457 MISSING_ATTRIBUTE (context, error, element_name, "name");
2460 if (version == NULL)
2462 MISSING_ATTRIBUTE (context, error, element_name, "version");
2466 if (!parse_include (context, ctx, name, version, error))
2469 ctx->dependencies = g_list_prepend (ctx->dependencies,
2470 g_strdup_printf ("%s-%s", name, version));
2473 state_switch (ctx, STATE_INCLUDE);
2476 if (start_interface (context, element_name,
2477 attribute_names, attribute_values,
2480 else if (start_implements (context, element_name,
2481 attribute_names, attribute_values,
2487 if (start_function (context, element_name,
2488 attribute_names, attribute_values,
2491 else if (start_member (context, element_name,
2492 attribute_names, attribute_values,
2498 if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2500 const gchar *name, *version, *shared_library;
2502 if (ctx->current_module != NULL)
2506 G_MARKUP_ERROR_INVALID_CONTENT,
2507 "Only one <namespace/> element is currently allowed per <repository/>");
2511 name = find_attribute ("name", attribute_names, attribute_values);
2512 version = find_attribute ("version", attribute_names, attribute_values);
2513 shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2516 MISSING_ATTRIBUTE (context, error, element_name, "name");
2517 else if (version == NULL)
2518 MISSING_ATTRIBUTE (context, error, element_name, "version");
2523 if (strcmp (name, ctx->namespace) != 0)
2526 G_MARKUP_ERROR_INVALID_CONTENT,
2527 "<namespace/> name element '%s' doesn't match file name '%s'",
2528 name, ctx->namespace);
2530 ctx->current_module = g_ir_module_new (name, version, shared_library);
2532 ctx->current_module->aliases = ctx->aliases;
2533 ctx->aliases = NULL;
2534 ctx->current_module->disguised_structures = ctx->disguised_structures;
2535 ctx->disguised_structures = NULL;
2537 for (l = ctx->include_modules; l; l = l->next)
2538 g_ir_module_add_include_module (ctx->current_module, l->data);
2540 g_list_free (ctx->include_modules);
2541 ctx->include_modules = NULL;
2543 ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2544 ctx->current_module->dependencies = ctx->dependencies;
2546 state_switch (ctx, STATE_NAMESPACE);
2553 if (start_property (context, element_name,
2554 attribute_names, attribute_values,
2557 else if (strcmp (element_name, "parameters") == 0 &&
2558 ctx->state == STATE_FUNCTION)
2560 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2564 else if (start_parameter (context, element_name,
2565 attribute_names, attribute_values,
2568 else if (strcmp (element_name, "prerequisite") == 0 &&
2569 ctx->state == STATE_INTERFACE)
2573 name = find_attribute ("name", attribute_names, attribute_values);
2575 state_switch (ctx, STATE_PREREQUISITE);
2578 MISSING_ATTRIBUTE (context, error, element_name, "name");
2581 GIrNodeInterface *iface;
2583 iface = (GIrNodeInterface *)CURRENT_NODE(ctx);
2584 iface->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
2588 else if (strcmp (element_name, "package") == 0 &&
2589 ctx->state == STATE_REPOSITORY)
2591 state_switch (ctx, STATE_PACKAGE);
2597 if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
2599 const gchar *version;
2601 version = find_attribute ("version", attribute_names, attribute_values);
2603 if (version == NULL)
2604 MISSING_ATTRIBUTE (context, error, element_name, "version");
2605 else if (strcmp (version, "1.0") != 0)
2608 G_MARKUP_ERROR_INVALID_CONTENT,
2609 "Unsupported version '%s'",
2612 state_switch (ctx, STATE_REPOSITORY);
2616 else if (start_return_value (context, element_name,
2617 attribute_names, attribute_values,
2620 else if (start_struct (context, element_name,
2621 attribute_names, attribute_values,
2627 if (start_union (context, element_name,
2628 attribute_names, attribute_values,
2634 if (start_type (context, element_name,
2635 attribute_names, attribute_values,
2641 if (start_vfunc (context, element_name,
2642 attribute_names, attribute_values,
2645 if (start_type (context, element_name,
2646 attribute_names, attribute_values,
2652 if (ctx->state != STATE_UNKNOWN)
2654 state_switch (ctx, STATE_UNKNOWN);
2655 ctx->unknown_depth = 1;
2659 ctx->unknown_depth += 1;
2665 g_markup_parse_context_get_position (context, &line_number, &char_number);
2667 fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message);
2668 backtrace_stderr ();
2673 require_one_of_end_elements (GMarkupParseContext *context,
2675 const char *actual_name,
2680 int line_number, char_number;
2681 const char *expected;
2682 gboolean matched = FALSE;
2684 va_start (args, error);
2686 while ((expected = va_arg (args, const char*)) != NULL)
2688 if (strcmp (expected, actual_name) == 0)
2700 g_markup_parse_context_get_position (context, &line_number, &char_number);
2703 G_MARKUP_ERROR_INVALID_CONTENT,
2704 "Unexpected end tag '%s' on line %d char %d; current state=%d",
2706 line_number, char_number, ctx->state);
2712 state_switch_end_struct_or_union (GMarkupParseContext *context,
2714 const gchar *element_name,
2718 if (ctx->node_stack == NULL)
2720 state_switch (ctx, STATE_NAMESPACE);
2724 if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2725 state_switch (ctx, STATE_STRUCT);
2726 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2727 state_switch (ctx, STATE_UNION);
2728 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2729 state_switch (ctx, STATE_CLASS);
2732 int line_number, char_number;
2733 g_markup_parse_context_get_position (context, &line_number, &char_number);
2736 G_MARKUP_ERROR_INVALID_CONTENT,
2737 "Unexpected end tag '%s' on line %d char %d",
2739 line_number, char_number);
2747 require_end_element (GMarkupParseContext *context,
2749 const char *expected_name,
2750 const char *actual_name,
2753 return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
2757 end_element_handler (GMarkupParseContext *context,
2758 const gchar *element_name,
2762 ParseContext *ctx = user_data;
2764 g_debug ("</%s>", element_name);
2770 /* no need to GError here, GMarkup already catches this */
2773 case STATE_REPOSITORY:
2774 state_switch (ctx, STATE_END);
2778 if (require_end_element (context, ctx, "include", element_name, error))
2780 state_switch (ctx, STATE_REPOSITORY);
2785 if (require_end_element (context, ctx, "package", element_name, error))
2787 state_switch (ctx, STATE_REPOSITORY);
2791 case STATE_NAMESPACE:
2792 if (require_end_element (context, ctx, "namespace", element_name, error))
2794 ctx->current_module = NULL;
2795 state_switch (ctx, STATE_REPOSITORY);
2800 if (require_end_element (context, ctx, "alias", element_name, error))
2802 state_switch (ctx, STATE_NAMESPACE);
2806 case STATE_FUNCTION_RETURN:
2807 if (strcmp ("type", element_name) == 0)
2809 if (require_end_element (context, ctx, "return-value", element_name, error))
2811 state_switch (ctx, STATE_FUNCTION);
2815 case STATE_FUNCTION_PARAMETERS:
2816 if (require_end_element (context, ctx, "parameters", element_name, error))
2818 state_switch (ctx, STATE_FUNCTION);
2822 case STATE_FUNCTION_PARAMETER:
2823 if (strcmp ("type", element_name) == 0)
2825 if (require_end_element (context, ctx, "parameter", element_name, error))
2827 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2831 case STATE_FUNCTION:
2834 if (ctx->node_stack == NULL)
2836 state_switch (ctx, STATE_NAMESPACE);
2840 if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
2841 state_switch (ctx, STATE_INTERFACE);
2842 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2843 state_switch (ctx, STATE_CLASS);
2844 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_BOXED)
2845 state_switch (ctx, STATE_BOXED);
2846 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2847 state_switch (ctx, STATE_STRUCT);
2848 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2849 state_switch (ctx, STATE_UNION);
2852 int line_number, char_number;
2853 g_markup_parse_context_get_position (context, &line_number, &char_number);
2856 G_MARKUP_ERROR_INVALID_CONTENT,
2857 "Unexpected end tag '%s' on line %d char %d",
2859 line_number, char_number);
2865 case STATE_CLASS_FIELD:
2866 if (strcmp ("type", element_name) == 0)
2868 if (require_end_element (context, ctx, "field", element_name, error))
2870 state_switch (ctx, STATE_CLASS);
2874 case STATE_CLASS_PROPERTY:
2875 if (strcmp ("type", element_name) == 0)
2877 if (require_end_element (context, ctx, "property", element_name, error))
2879 state_switch (ctx, STATE_CLASS);
2884 if (require_end_element (context, ctx, "class", element_name, error))
2887 state_switch (ctx, STATE_NAMESPACE);
2891 case STATE_ERRORDOMAIN:
2892 if (require_end_element (context, ctx, "errordomain", element_name, error))
2895 state_switch (ctx, STATE_NAMESPACE);
2899 case STATE_INTERFACE_PROPERTY:
2900 if (strcmp ("type", element_name) == 0)
2902 if (require_end_element (context, ctx, "property", element_name, error))
2904 state_switch (ctx, STATE_INTERFACE);
2908 case STATE_INTERFACE_FIELD:
2909 if (strcmp ("type", element_name) == 0)
2911 if (require_end_element (context, ctx, "field", element_name, error))
2913 state_switch (ctx, STATE_INTERFACE);
2917 case STATE_INTERFACE:
2918 if (require_end_element (context, ctx, "interface", element_name, error))
2921 state_switch (ctx, STATE_NAMESPACE);
2926 if (strcmp ("member", element_name) == 0)
2928 else if (require_one_of_end_elements (context, ctx,
2929 element_name, error, "enumeration",
2933 state_switch (ctx, STATE_NAMESPACE);
2938 if (require_end_element (context, ctx, "glib:boxed", element_name, error))
2941 state_switch (ctx, STATE_NAMESPACE);
2945 case STATE_BOXED_FIELD:
2946 if (strcmp ("type", element_name) == 0)
2948 if (require_end_element (context, ctx, "field", element_name, error))
2950 state_switch (ctx, STATE_BOXED);
2954 case STATE_STRUCT_FIELD:
2955 if (strcmp ("type", element_name) == 0)
2957 if (require_end_element (context, ctx, "field", element_name, error))
2959 state_switch (ctx, STATE_STRUCT);
2964 if (require_end_element (context, ctx, "record", element_name, error))
2966 state_switch_end_struct_or_union (context, ctx, element_name, error);
2970 case STATE_UNION_FIELD:
2971 if (strcmp ("type", element_name) == 0)
2973 if (require_end_element (context, ctx, "field", element_name, error))
2975 state_switch (ctx, STATE_UNION);
2980 if (require_end_element (context, ctx, "union", element_name, error))
2982 state_switch_end_struct_or_union (context, ctx, element_name, error);
2985 case STATE_IMPLEMENTS:
2986 if (strcmp ("interface", element_name) == 0)
2988 if (require_end_element (context, ctx, "implements", element_name, error))
2989 state_switch (ctx, STATE_CLASS);
2991 case STATE_PREREQUISITE:
2992 if (require_end_element (context, ctx, "prerequisite", element_name, error))
2993 state_switch (ctx, STATE_INTERFACE);
2995 case STATE_NAMESPACE_CONSTANT:
2996 case STATE_CLASS_CONSTANT:
2997 case STATE_INTERFACE_CONSTANT:
2998 if (strcmp ("type", element_name) == 0)
3000 if (require_end_element (context, ctx, "constant", element_name, error))
3005 case STATE_NAMESPACE_CONSTANT:
3006 state_switch (ctx, STATE_NAMESPACE);
3008 case STATE_CLASS_CONSTANT:
3009 state_switch (ctx, STATE_CLASS);
3011 case STATE_INTERFACE_CONSTANT:
3012 state_switch (ctx, STATE_INTERFACE);
3015 g_assert_not_reached ();
3021 if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
3022 (strcmp ("varargs", element_name) == 0))
3028 ctx->unknown_depth -= 1;
3029 if (ctx->unknown_depth == 0)
3030 state_switch (ctx, ctx->prev_state);
3033 g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
3038 text_handler (GMarkupParseContext *context,
3044 /* FIXME warn about non-whitespace text */
3048 cleanup (GMarkupParseContext *context,
3052 ParseContext *ctx = user_data;
3055 for (m = ctx->modules; m; m = m->next)
3056 g_ir_module_free (m->data);
3057 g_list_free (ctx->modules);
3058 ctx->modules = NULL;
3060 ctx->current_module = NULL;
3064 post_filter_toplevel_varargs_functions (GList *list,
3065 GList **varargs_callbacks_out)
3068 GList *varargs_callbacks = *varargs_callbacks_out;
3074 GIrNode *node = iter->data;
3078 if (node->type == G_IR_NODE_FUNCTION)
3080 if (((GIrNodeFunction*)node)->is_varargs)
3082 list = g_list_delete_link (list, link);
3085 if (node->type == G_IR_NODE_CALLBACK)
3087 if (((GIrNodeFunction*)node)->is_varargs)
3089 varargs_callbacks = g_list_append (varargs_callbacks,
3091 list = g_list_delete_link (list, link);
3096 *varargs_callbacks_out = varargs_callbacks;
3102 post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out)
3105 GList *varargs_callbacks;
3107 list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out);
3109 varargs_callbacks = *varargs_callbacks_out;
3115 GIrNode *node = iter->data;
3119 if (node->type == G_IR_NODE_FUNCTION)
3122 gboolean function_done = FALSE;
3124 for (param = ((GIrNodeFunction *)node)->parameters;
3126 param = param->next)
3128 GIrNodeParam *node = (GIrNodeParam *)param->data;
3133 if (node->type->is_interface)
3136 for (callback = varargs_callbacks;
3138 callback = callback->next)
3140 if (!strcmp (node->type->interface,
3141 ((GIrNode *)varargs_callbacks->data)->name))
3143 list = g_list_delete_link (list, link);
3144 function_done = TRUE;
3153 *varargs_callbacks_out = varargs_callbacks;
3159 post_filter (GIrModule *module)
3162 GList *varargs_callbacks = NULL;
3164 module->entries = post_filter_varargs_functions (module->entries,
3165 &varargs_callbacks);
3166 iter = module->entries;
3169 GIrNode *node = iter->data;
3173 if (node->type == G_IR_NODE_OBJECT ||
3174 node->type == G_IR_NODE_INTERFACE)
3176 GIrNodeInterface *iface = (GIrNodeInterface*)node;
3177 iface->members = post_filter_varargs_functions (iface->members,
3178 &varargs_callbacks);
3180 else if (node->type == G_IR_NODE_BOXED)
3182 GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
3183 boxed->members = post_filter_varargs_functions (boxed->members,
3184 &varargs_callbacks);
3186 else if (node->type == G_IR_NODE_STRUCT)
3188 GIrNodeStruct *iface = (GIrNodeStruct*)node;
3189 iface->members = post_filter_varargs_functions (iface->members,
3190 &varargs_callbacks);
3192 else if (node->type == G_IR_NODE_UNION)
3194 GIrNodeUnion *iface = (GIrNodeUnion*)node;
3195 iface->members = post_filter_varargs_functions (iface->members,
3196 &varargs_callbacks);
3199 g_list_free (varargs_callbacks);
3203 * g_ir_parser_parse_string:
3204 * @parser: a #GIrParser
3205 * @namespace: the namespace of the string
3206 * @buffer: the data containing the XML
3207 * @length: length of the data
3208 * @error: return location for a #GError, or %NULL
3210 * Parse a string that holds a complete GIR XML file, and return a list of a
3211 * a #GirModule for each <namespace/> element within the file.
3213 * Returns: a newly allocated list of #GIrModule. The modules themselves
3214 * are owned by the #GIrParser and will be freed along with the parser.
3217 g_ir_parser_parse_string (GIrParser *parser,
3218 const gchar *namespace,
3219 const gchar *buffer,
3223 ParseContext ctx = { 0 };
3224 GMarkupParseContext *context;
3226 ctx.parser = parser;
3227 ctx.state = STATE_START;
3228 ctx.namespace = namespace;
3229 ctx.include_modules = NULL;
3230 ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
3231 ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
3233 ctx.dependencies = NULL;
3234 ctx.current_module = NULL;
3236 context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
3238 if (!g_markup_parse_context_parse (context, buffer, length, error))
3241 if (!g_markup_parse_context_end_parse (context, error))
3244 g_markup_parse_context_free (context);
3246 context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL);
3247 if (!g_markup_parse_context_parse (context, buffer, length, error))
3250 if (!g_markup_parse_context_end_parse (context, error))
3253 parser->parsed_modules = g_list_concat (g_list_copy (ctx.modules),
3254 parser->parsed_modules);
3258 if (ctx.modules == NULL)
3260 /* An error occurred before we created a module, so we haven't
3261 * transferred ownership of these hash tables to the module.
3263 if (ctx.aliases != NULL)
3264 g_hash_table_destroy (ctx.aliases);
3265 if (ctx.disguised_structures != NULL)
3266 g_hash_table_destroy (ctx.disguised_structures);
3267 g_list_free (ctx.include_modules);
3270 g_markup_parse_context_free (context);
3276 * g_ir_parser_parse_file:
3277 * @parser: a #GIrParser
3278 * @filename: filename to parse
3279 * @error: return location for a #GError, or %NULL
3281 * Parse GIR XML file, and return a list of a a #GirModule for each
3282 * <namespace/> element within the file.
3284 * Returns: a newly allocated list of #GIrModule. The modules themselves
3285 * are owned by the #GIrParser and will be freed along with the parser.
3288 g_ir_parser_parse_file (GIrParser *parser,
3289 const gchar *filename,
3300 if (!g_str_has_suffix (filename, ".gir"))
3304 G_MARKUP_ERROR_INVALID_CONTENT,
3305 "Expected filename to end with '.gir'");
3309 g_debug ("[parsing] filename %s", filename);
3311 slash = g_strrstr (filename, "/");
3313 namespace = g_strdup (filename);
3315 namespace = g_strdup (slash+1);
3316 namespace[strlen(namespace)-4] = '\0';
3318 /* Remove version */
3319 dash = strstr (namespace, "-");
3323 if (!g_file_get_contents (filename, &buffer, &length, error))
3326 modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error);
3328 for (iter = modules; iter; iter = iter->next)
3330 post_filter ((GIrModule*)iter->data);