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 */
47 STATE_FUNCTION_RETURN,
48 STATE_FUNCTION_PARAMETERS,
49 STATE_FUNCTION_PARAMETER, /* 10 */
54 STATE_INTERFACE_PROPERTY, /* 15 */
55 STATE_INTERFACE_FIELD,
59 STATE_BOXED_FIELD, /* 20 */
64 STATE_UNION_FIELD, /* 25 */
65 STATE_NAMESPACE_CONSTANT,
67 STATE_INTERFACE_CONSTANT,
73 typedef struct _ParseContext ParseContext;
80 ParseState prev_state;
83 GList *include_modules;
86 GHashTable *disguised_structures;
88 const char *namespace;
89 GIrModule *current_module;
91 GIrNode *current_typed;
94 GList *type_parameters;
97 #define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data))
99 static void start_element_handler (GMarkupParseContext *context,
100 const gchar *element_name,
101 const gchar **attribute_names,
102 const gchar **attribute_values,
105 static void end_element_handler (GMarkupParseContext *context,
106 const gchar *element_name,
109 static void text_handler (GMarkupParseContext *context,
114 static void cleanup (GMarkupParseContext *context,
118 static GMarkupParser markup_parser =
120 start_element_handler,
128 start_alias (GMarkupParseContext *context,
129 const gchar *element_name,
130 const gchar **attribute_names,
131 const gchar **attribute_values,
135 static const gchar *find_attribute (const gchar *name,
136 const gchar **attribute_names,
137 const gchar **attribute_values);
141 g_ir_parser_new (void)
143 GIrParser *parser = g_slice_new0 (GIrParser);
149 g_ir_parser_free (GIrParser *parser)
153 if (parser->includes)
154 g_strfreev (parser->includes);
156 for (l = parser->parsed_modules; l; l = l->next)
157 g_ir_module_free (l->data);
159 g_slice_free (GIrParser, parser);
163 g_ir_parser_set_includes (GIrParser *parser,
164 const gchar *const *includes)
166 if (parser->includes)
167 g_strfreev (parser->includes);
169 parser->includes = g_strdupv ((char **)includes);
173 firstpass_start_element_handler (GMarkupParseContext *context,
174 const gchar *element_name,
175 const gchar **attribute_names,
176 const gchar **attribute_values,
180 ParseContext *ctx = user_data;
182 if (strcmp (element_name, "alias") == 0)
184 start_alias (context, element_name, attribute_names, attribute_values,
187 else if (strcmp (element_name, "record") == 0)
190 const gchar *disguised;
192 name = find_attribute ("name", attribute_names, attribute_values);
193 disguised = find_attribute ("disguised", attribute_names, attribute_values);
195 if (disguised && strcmp (disguised, "1") == 0)
199 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
200 g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1));
206 firstpass_end_element_handler (GMarkupParseContext *context,
207 const gchar *element_name,
213 static GMarkupParser firstpass_parser =
215 firstpass_start_element_handler,
216 firstpass_end_element_handler,
223 locate_gir (GIrParser *parser,
227 const gchar *const *datadirs;
228 const gchar *const *dir;
232 datadirs = g_get_system_data_dirs ();
234 girname = g_strdup_printf ("%s-%s.gir", name, version);
236 if (parser->includes != NULL)
238 for (dir = (const gchar *const *)parser->includes; *dir; dir++)
240 path = g_build_filename (*dir, girname, NULL);
241 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
247 for (dir = datadirs; *dir; dir++)
249 path = g_build_filename (*dir, "gir-1.0", girname, NULL);
250 if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
259 #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \
261 int line_number, char_number; \
262 g_markup_parse_context_get_position (context, &line_number, &char_number); \
263 g_set_error (error, \
265 G_MARKUP_ERROR_INVALID_CONTENT, \
266 "Line %d, character %d: The attribute '%s' on the element '%s' must be specified", \
267 line_number, char_number, attribute, element); \
271 backtrace_stderr (void)
273 #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
279 size = backtrace (array, 50);
280 strings = (char**) backtrace_symbols (array, size);
282 fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size);
284 for (i = 0; i < size; i++)
285 fprintf (stderr, "%s\n", strings[i]);
287 fprintf (stderr, "--- END BACKTRACE ---\n", size);
295 find_attribute (const gchar *name,
296 const gchar **attribute_names,
297 const gchar **attribute_values)
301 for (i = 0; attribute_names[i] != NULL; i++)
302 if (strcmp (attribute_names[i], name) == 0)
303 return attribute_values[i];
309 state_switch (ParseContext *ctx, ParseState newstate)
311 g_debug ("State: %d", newstate);
312 ctx->prev_state = ctx->state;
313 ctx->state = newstate;
317 pop_node (ParseContext *ctx)
319 g_assert (ctx->node_stack != 0);
321 GSList *top = ctx->node_stack;
322 GIrNode *node = top->data;
324 g_debug ("popping node %d %s", node->type, node->name);
325 ctx->node_stack = top->next;
326 g_slist_free_1 (top);
331 push_node (ParseContext *ctx, GIrNode *node)
333 g_debug ("pushing node %d %s", node->type, node->name);
334 ctx->node_stack = g_slist_prepend (ctx->node_stack, node);
337 static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib,
338 gboolean in_gobject);
346 static BasicTypeInfo basic_types[] = {
347 { "none", GI_TYPE_TAG_VOID, 0 },
348 { "any", GI_TYPE_TAG_VOID, 1 },
350 { "bool", GI_TYPE_TAG_BOOLEAN, 0 },
351 { "char", GI_TYPE_TAG_INT8, 0 },
352 { "int8", GI_TYPE_TAG_INT8, 0 },
353 { "uint8", GI_TYPE_TAG_UINT8, 0 },
354 { "int16", GI_TYPE_TAG_INT16, 0 },
355 { "uint16", GI_TYPE_TAG_UINT16, 0 },
356 { "int32", GI_TYPE_TAG_INT32, 0 },
357 { "uint32", GI_TYPE_TAG_UINT32, 0 },
358 { "int64", GI_TYPE_TAG_INT64, 0 },
359 { "uint64", GI_TYPE_TAG_UINT64, 0 },
360 { "int", GI_TYPE_TAG_INT, 0 },
361 { "uint", GI_TYPE_TAG_UINT, 0 },
362 { "long", GI_TYPE_TAG_LONG, 0 },
363 { "ulong", GI_TYPE_TAG_ULONG, 0 },
364 { "ssize_t", GI_TYPE_TAG_SSIZE, 0 },
365 { "ssize", GI_TYPE_TAG_SSIZE, 0 },
366 { "size_t", GI_TYPE_TAG_SIZE, 0 },
367 { "size", GI_TYPE_TAG_SIZE, 0 },
368 { "float", GI_TYPE_TAG_FLOAT, 0 },
369 { "double", GI_TYPE_TAG_DOUBLE, 0 },
370 { "time_t", GI_TYPE_TAG_TIME_T, 0 },
371 { "GType", GI_TYPE_TAG_GTYPE, 0 },
372 { "utf8", GI_TYPE_TAG_UTF8, 1 },
373 { "filename", GI_TYPE_TAG_FILENAME,1 },
376 static const BasicTypeInfo *
377 parse_basic (const char *str)
380 gint n_basic = G_N_ELEMENTS (basic_types);
382 for (i = 0; i < n_basic; i++)
384 if (g_str_has_prefix (str, basic_types[i].str))
385 return &(basic_types[i]);
391 parse_type_internal (const gchar *str, char **next, gboolean in_glib,
394 const BasicTypeInfo *basic;
396 char *temporary_type = NULL;
398 type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
400 type->unparsed = g_strdup (str);
402 /* See comment below on GLib.List handling */
403 if (in_gobject && strcmp (str, "Type") == 0)
405 temporary_type = g_strdup ("GLib.Type");
406 str = temporary_type;
409 basic = parse_basic (str);
412 type->is_basic = TRUE;
413 type->tag = basic->tag;
414 type->is_pointer = basic->pointer;
416 str += strlen(basic->str);
420 /* If we're inside GLib, handle "List" etc. by prefixing with
421 * "GLib." so the parsing code below doesn't have to get more
424 if (g_str_has_prefix (str, "List<") ||
425 strcmp (str, "List") == 0)
427 temporary_type = g_strdup_printf ("GLib.List%s", str + 4);
428 str = temporary_type;
430 else if (g_str_has_prefix (str, "SList<") ||
431 strcmp (str, "SList") == 0)
433 temporary_type = g_strdup_printf ("GLib.SList%s", str + 5);
434 str = temporary_type;
436 else if (g_str_has_prefix (str, "HashTable<") ||
437 strcmp (str, "HashTable") == 0)
439 temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9);
440 str = temporary_type;
442 else if (g_str_has_prefix (str, "Error<") ||
443 strcmp (str, "Error") == 0)
445 temporary_type = g_strdup_printf ("GLib.Error%s", str + 5);
446 str = temporary_type;
451 /* found a basic type */;
452 else if (g_str_has_prefix (str, "GLib.List") ||
453 g_str_has_prefix (str, "GLib.SList"))
455 str += strlen ("GLib.");
456 if (g_str_has_prefix (str, "List"))
458 type->tag = GI_TYPE_TAG_GLIST;
459 type->is_glist = TRUE;
460 type->is_pointer = TRUE;
461 str += strlen ("List");
465 type->tag = GI_TYPE_TAG_GSLIST;
466 type->is_gslist = TRUE;
467 type->is_pointer = TRUE;
468 str += strlen ("SList");
471 else if (g_str_has_prefix (str, "GLib.HashTable"))
473 str += strlen ("GLib.");
475 type->tag = GI_TYPE_TAG_GHASH;
476 type->is_ghashtable = TRUE;
477 type->is_pointer = TRUE;
478 str += strlen ("HashTable");
480 else if (g_str_has_prefix (str, "GLib.Error"))
482 str += strlen ("GLib.");
484 type->tag = GI_TYPE_TAG_ERROR;
485 type->is_error = TRUE;
486 type->is_pointer = TRUE;
487 str += strlen ("Error");
494 end = strchr (str, '>');
495 tmp = g_strndup (str, end - str);
496 type->errors = g_strsplit (tmp, ",", 0);
504 type->tag = GI_TYPE_TAG_INTERFACE;
505 type->is_interface = TRUE;
506 const char *start = str;
508 /* must be an interface type */
509 while (g_ascii_isalnum (*str) ||
516 type->interface = g_strndup (start, str - start);
521 g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR);
522 g_free (temporary_type);
526 g_ir_node_free ((GIrNode *)type);
527 g_free (temporary_type);
532 resolve_aliases (ParseContext *ctx, const gchar *type)
536 GSList *seen_values = NULL;
540 if (strchr (type, '.') == NULL)
542 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
551 seen_values = g_slist_prepend (seen_values, (char*)lookup);
552 while (g_hash_table_lookup_extended (ctx->current_module->aliases, lookup, &orig, &value))
554 g_debug ("Resolved: %s => %s\n", lookup, (char*)value);
556 if (g_slist_find_custom (seen_values, lookup,
557 (GCompareFunc)strcmp) != NULL)
559 seen_values = g_slist_prepend (seen_values, (gchar*)lookup);
561 g_slist_free (seen_values);
563 if (lookup == prefixed)
572 is_disguised_structure (ParseContext *ctx, const gchar *type)
578 if (strchr (type, '.') == NULL)
580 prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
589 result = g_hash_table_lookup (ctx->current_module->disguised_structures,
598 parse_type (ParseContext *ctx, const gchar *type)
601 const BasicTypeInfo *basic;
602 gboolean in_glib, in_gobject;
604 in_glib = strcmp (ctx->namespace, "GLib") == 0;
605 in_gobject = strcmp (ctx->namespace, "GObject") == 0;
607 /* Do not search aliases for basic types */
608 basic = parse_basic (type);
610 type = resolve_aliases (ctx, type);
612 node = parse_type_internal (type, NULL, in_glib, in_gobject);
614 g_debug ("Parsed type: %s => %d", type, node->tag);
616 g_critical ("Failed to parse type: '%s'", type);
622 start_glib_boxed (GMarkupParseContext *context,
623 const gchar *element_name,
624 const gchar **attribute_names,
625 const gchar **attribute_values,
630 const gchar *typename;
631 const gchar *typeinit;
632 const gchar *deprecated;
635 if (!(strcmp (element_name, "glib:boxed") == 0 &&
636 ctx->state == STATE_NAMESPACE))
639 name = find_attribute ("glib:name", attribute_names, attribute_values);
640 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
641 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
642 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
646 MISSING_ATTRIBUTE (context, error, element_name, "glib:name");
649 else if (typename == NULL)
651 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
654 else if (typeinit == NULL)
656 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
660 boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED);
662 ((GIrNode *)boxed)->name = g_strdup (name);
663 boxed->gtype_name = g_strdup (typename);
664 boxed->gtype_init = g_strdup (typeinit);
666 boxed->deprecated = TRUE;
668 boxed->deprecated = FALSE;
670 push_node (ctx, (GIrNode *)boxed);
671 ctx->current_module->entries =
672 g_list_append (ctx->current_module->entries, boxed);
674 state_switch (ctx, STATE_BOXED);
680 start_function (GMarkupParseContext *context,
681 const gchar *element_name,
682 const gchar **attribute_names,
683 const gchar **attribute_values,
689 const gchar *deprecated;
691 GIrNodeFunction *function;
692 gboolean found = FALSE;
696 case STATE_NAMESPACE:
697 found = (strcmp (element_name, "function") == 0 ||
698 strcmp (element_name, "callback") == 0);
701 found = strcmp (element_name, "function") == 0;
706 found = (found || strcmp (element_name, "constructor") == 0);
708 case STATE_INTERFACE:
710 strcmp (element_name, "method") == 0 ||
711 strcmp (element_name, "callback") == 0);
720 name = find_attribute ("name", attribute_names, attribute_values);
721 symbol = find_attribute ("c:identifier", attribute_names, attribute_values);
722 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
723 throws = find_attribute ("throws", attribute_names, attribute_values);
727 MISSING_ATTRIBUTE (context, error, element_name, "name");
730 else if (strcmp (element_name, "callback") != 0 && symbol == NULL)
732 MISSING_ATTRIBUTE (context, error, element_name, "c:identifier");
736 function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION);
738 ((GIrNode *)function)->name = g_strdup (name);
739 function->symbol = g_strdup (symbol);
740 function->parameters = NULL;
742 function->deprecated = TRUE;
744 function->deprecated = FALSE;
746 if (strcmp (element_name, "method") == 0 ||
747 strcmp (element_name, "constructor") == 0)
749 function->is_method = TRUE;
751 if (strcmp (element_name, "constructor") == 0)
752 function->is_constructor = TRUE;
754 function->is_constructor = FALSE;
758 function->is_method = FALSE;
759 function->is_setter = FALSE;
760 function->is_getter = FALSE;
761 function->is_constructor = FALSE;
762 if (strcmp (element_name, "callback") == 0)
763 ((GIrNode *)function)->type = G_IR_NODE_CALLBACK;
766 if (throws && strcmp (throws, "1") == 0)
767 function->throws = TRUE;
769 function->throws = FALSE;
771 if (ctx->node_stack == NULL)
773 ctx->current_module->entries =
774 g_list_append (ctx->current_module->entries, function);
777 switch (CURRENT_NODE (ctx)->type)
779 case G_IR_NODE_INTERFACE:
780 case G_IR_NODE_OBJECT:
782 GIrNodeInterface *iface;
784 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
785 iface->members = g_list_append (iface->members, function);
788 case G_IR_NODE_BOXED:
792 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
793 boxed->members = g_list_append (boxed->members, function);
796 case G_IR_NODE_STRUCT:
798 GIrNodeStruct *struct_;
800 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
801 struct_->members = g_list_append (struct_->members, function); }
803 case G_IR_NODE_UNION:
805 GIrNodeUnion *union_;
807 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
808 union_->members = g_list_append (union_->members, function);
812 g_assert_not_reached ();
815 push_node(ctx, (GIrNode *)function);
816 state_switch (ctx, STATE_FUNCTION);
822 parse_param_transfer (GIrNodeParam *param, const gchar *transfer)
824 if (transfer == NULL)
826 g_warning ("required attribute 'transfer-ownership' missing");
828 else if (strcmp (transfer, "none") == 0)
830 param->transfer = FALSE;
831 param->shallow_transfer = FALSE;
833 else if (strcmp (transfer, "container") == 0)
835 param->transfer = FALSE;
836 param->shallow_transfer = TRUE;
838 else if (strcmp (transfer, "full") == 0)
840 param->transfer = TRUE;
841 param->shallow_transfer = FALSE;
845 g_warning ("Unknown transfer-ownership value: %s", transfer);
850 start_parameter (GMarkupParseContext *context,
851 const gchar *element_name,
852 const gchar **attribute_names,
853 const gchar **attribute_values,
858 const gchar *direction;
861 const gchar *optional;
862 const gchar *allow_none;
863 const gchar *transfer;
865 const gchar *closure;
866 const gchar *destroy;
869 if (!(strcmp (element_name, "parameter") == 0 &&
870 ctx->state == STATE_FUNCTION_PARAMETERS))
873 name = find_attribute ("name", attribute_names, attribute_values);
874 direction = find_attribute ("direction", attribute_names, attribute_values);
875 retval = find_attribute ("retval", attribute_names, attribute_values);
876 dipper = find_attribute ("dipper", attribute_names, attribute_values);
877 optional = find_attribute ("optional", attribute_names, attribute_values);
878 allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
879 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
880 scope = find_attribute ("scope", attribute_names, attribute_values);
881 closure = find_attribute ("closure", attribute_names, attribute_values);
882 destroy = find_attribute ("destroy", attribute_names, attribute_values);
887 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
889 ctx->current_typed = (GIrNode*) param;
890 ctx->current_typed->name = g_strdup (name);
892 state_switch (ctx, STATE_FUNCTION_PARAMETER);
894 if (direction && strcmp (direction, "out") == 0)
899 else if (direction && strcmp (direction, "inout") == 0)
910 if (retval && strcmp (retval, "1") == 0)
911 param->retval = TRUE;
913 param->retval = FALSE;
915 if (dipper && strcmp (dipper, "1") == 0)
916 param->dipper = TRUE;
918 param->dipper = FALSE;
920 if (optional && strcmp (optional, "1") == 0)
921 param->optional = TRUE;
923 param->optional = FALSE;
925 if (allow_none && strcmp (allow_none, "1") == 0)
926 param->allow_none = TRUE;
928 param->allow_none = FALSE;
930 parse_param_transfer (param, transfer);
932 if (scope && strcmp (scope, "call") == 0)
933 param->scope = GI_SCOPE_TYPE_CALL;
934 else if (scope && strcmp (scope, "object") == 0)
935 param->scope = GI_SCOPE_TYPE_OBJECT;
936 else if (scope && strcmp (scope, "async") == 0)
937 param->scope = GI_SCOPE_TYPE_ASYNC;
938 else if (scope && strcmp (scope, "notified") == 0)
939 param->scope = GI_SCOPE_TYPE_NOTIFIED;
941 param->scope = GI_SCOPE_TYPE_INVALID;
943 param->closure = closure ? atoi (closure) : -1;
944 param->destroy = destroy ? atoi (destroy) : -1;
946 ((GIrNode *)param)->name = g_strdup (name);
948 switch (CURRENT_NODE (ctx)->type)
950 case G_IR_NODE_FUNCTION:
951 case G_IR_NODE_CALLBACK:
953 GIrNodeFunction *func;
955 func = (GIrNodeFunction *)CURRENT_NODE (ctx);
956 func->parameters = g_list_append (func->parameters, param);
959 case G_IR_NODE_SIGNAL:
961 GIrNodeSignal *signal;
963 signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
964 signal->parameters = g_list_append (signal->parameters, param);
967 case G_IR_NODE_VFUNC:
971 vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
972 vfunc->parameters = g_list_append (vfunc->parameters, param);
976 g_assert_not_reached ();
983 start_field (GMarkupParseContext *context,
984 const gchar *element_name,
985 const gchar **attribute_names,
986 const gchar **attribute_values,
991 const gchar *readable;
992 const gchar *writable;
1003 case STATE_INTERFACE:
1009 if (strcmp (element_name, "field") != 0)
1012 name = find_attribute ("name", attribute_names, attribute_values);
1013 readable = find_attribute ("readable", attribute_names, attribute_values);
1014 writable = find_attribute ("writable", attribute_names, attribute_values);
1015 bits = find_attribute ("bits", attribute_names, attribute_values);
1016 branch = find_attribute ("branch", attribute_names, attribute_values);
1020 MISSING_ATTRIBUTE (context, error, element_name, "name");
1024 field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD);
1025 ctx->current_typed = (GIrNode*) field;
1026 ((GIrNode *)field)->name = g_strdup (name);
1027 /* Fields are assumed to be read-only.
1028 * (see also girwriter.py and generate.c)
1030 field->readable = readable == NULL || strcmp (readable, "0") == 0;
1031 field->writable = writable != NULL && strcmp (writable, "1") == 0;
1034 field->bits = atoi (bits);
1038 switch (CURRENT_NODE (ctx)->type)
1040 case G_IR_NODE_OBJECT:
1042 GIrNodeInterface *iface;
1044 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1045 iface->members = g_list_append (iface->members, field);
1046 state_switch (ctx, STATE_CLASS_FIELD);
1049 case G_IR_NODE_INTERFACE:
1051 GIrNodeInterface *iface;
1053 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1054 iface->members = g_list_append (iface->members, field);
1055 state_switch (ctx, STATE_INTERFACE_FIELD);
1058 case G_IR_NODE_BOXED:
1060 GIrNodeBoxed *boxed;
1062 boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx);
1063 boxed->members = g_list_append (boxed->members, field);
1064 state_switch (ctx, STATE_BOXED_FIELD);
1067 case G_IR_NODE_STRUCT:
1069 GIrNodeStruct *struct_;
1071 struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx);
1072 struct_->members = g_list_append (struct_->members, field);
1073 state_switch (ctx, STATE_STRUCT_FIELD);
1076 case G_IR_NODE_UNION:
1078 GIrNodeUnion *union_;
1080 union_ = (GIrNodeUnion *)CURRENT_NODE (ctx);
1081 union_->members = g_list_append (union_->members, field);
1084 GIrNodeConstant *constant;
1086 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1087 ((GIrNode *)constant)->name = g_strdup (name);
1088 constant->value = g_strdup (branch);
1089 constant->type = union_->discriminator_type;
1090 constant->deprecated = FALSE;
1092 union_->discriminators = g_list_append (union_->discriminators, constant);
1094 state_switch (ctx, STATE_UNION_FIELD);
1098 g_assert_not_reached ();
1105 start_alias (GMarkupParseContext *context,
1106 const gchar *element_name,
1107 const gchar **attribute_names,
1108 const gchar **attribute_values,
1113 const gchar *target;
1117 name = find_attribute ("name", attribute_names, attribute_values);
1120 MISSING_ATTRIBUTE (context, error, element_name, "name");
1124 target = find_attribute ("target", attribute_names, attribute_values);
1127 MISSING_ATTRIBUTE (context, error, element_name, "target");
1131 value = g_strdup (target);
1132 key = g_strdup_printf ("%s.%s", ctx->namespace, name);
1133 if (!strchr (target, '.'))
1135 const BasicTypeInfo *basic = parse_basic (target);
1139 /* For non-basic types, re-qualify the interface */
1140 value = g_strdup_printf ("%s.%s", ctx->namespace, target);
1143 g_hash_table_replace (ctx->aliases, key, value);
1149 start_enum (GMarkupParseContext *context,
1150 const gchar *element_name,
1151 const gchar **attribute_names,
1152 const gchar **attribute_values,
1156 if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
1157 (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))
1160 const gchar *typename;
1161 const gchar *typeinit;
1162 const gchar *deprecated;
1164 name = find_attribute ("name", attribute_names, attribute_values);
1165 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1166 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1167 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1170 MISSING_ATTRIBUTE (context, error, element_name, "name");
1175 if (strcmp (element_name, "enumeration") == 0)
1176 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM);
1178 enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS);
1179 ((GIrNode *)enum_)->name = g_strdup (name);
1180 enum_->gtype_name = g_strdup (typename);
1181 enum_->gtype_init = g_strdup (typeinit);
1183 enum_->deprecated = TRUE;
1185 enum_->deprecated = FALSE;
1187 push_node (ctx, (GIrNode *) enum_);
1188 ctx->current_module->entries =
1189 g_list_append (ctx->current_module->entries, enum_);
1191 state_switch (ctx, STATE_ENUM);
1200 start_property (GMarkupParseContext *context,
1201 const gchar *element_name,
1202 const gchar **attribute_names,
1203 const gchar **attribute_values,
1207 if (strcmp (element_name, "property") == 0 &&
1208 (ctx->state == STATE_CLASS ||
1209 ctx->state == STATE_INTERFACE))
1212 const gchar *readable;
1213 const gchar *writable;
1214 const gchar *construct;
1215 const gchar *construct_only;
1217 name = find_attribute ("name", attribute_names, attribute_values);
1218 readable = find_attribute ("readable", attribute_names, attribute_values);
1219 writable = find_attribute ("writable", attribute_names, attribute_values);
1220 construct = find_attribute ("construct", attribute_names, attribute_values);
1221 construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
1224 MISSING_ATTRIBUTE (context, error, element_name, "name");
1227 GIrNodeProperty *property;
1228 GIrNodeInterface *iface;
1230 property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
1231 ctx->current_typed = (GIrNode*) property;
1233 ((GIrNode *)property)->name = g_strdup (name);
1235 /* Assume properties are readable */
1236 if (readable == NULL || strcmp (readable, "1") == 0)
1237 property->readable = TRUE;
1239 property->readable = FALSE;
1240 if (writable && strcmp (writable, "1") == 0)
1241 property->writable = TRUE;
1243 property->writable = FALSE;
1244 if (construct && strcmp (construct, "1") == 0)
1245 property->construct = TRUE;
1247 property->construct = FALSE;
1248 if (construct_only && strcmp (construct_only, "1") == 0)
1249 property->construct_only = TRUE;
1251 property->construct_only = FALSE;
1253 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1254 iface->members = g_list_append (iface->members, property);
1256 if (ctx->state == STATE_CLASS)
1257 state_switch (ctx, STATE_CLASS_PROPERTY);
1258 else if (ctx->state == STATE_INTERFACE)
1259 state_switch (ctx, STATE_INTERFACE_PROPERTY);
1261 g_assert_not_reached ();
1270 parse_value (const gchar *str)
1274 /* FIXME just a quick hack */
1275 shift_op = strstr (str, "<<");
1281 base = strtol (str, NULL, 10);
1282 shift = strtol (shift_op + 3, NULL, 10);
1284 return base << shift;
1287 return strtol (str, NULL, 10);
1293 start_member (GMarkupParseContext *context,
1294 const gchar *element_name,
1295 const gchar **attribute_names,
1296 const gchar **attribute_values,
1300 if (strcmp (element_name, "member") == 0 &&
1301 ctx->state == STATE_ENUM)
1305 const gchar *deprecated;
1307 name = find_attribute ("name", attribute_names, attribute_values);
1308 value = find_attribute ("value", attribute_names, attribute_values);
1309 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1312 MISSING_ATTRIBUTE (context, error, element_name, "name");
1316 GIrNodeValue *value_;
1318 value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
1320 ((GIrNode *)value_)->name = g_strdup (name);
1322 value_->value = parse_value (value);
1325 value_->deprecated = TRUE;
1327 value_->deprecated = FALSE;
1329 enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx);
1330 enum_->values = g_list_append (enum_->values, value_);
1339 start_constant (GMarkupParseContext *context,
1340 const gchar *element_name,
1341 const gchar **attribute_names,
1342 const gchar **attribute_values,
1346 if (strcmp (element_name, "constant") == 0 &&
1347 (ctx->state == STATE_NAMESPACE ||
1348 ctx->state == STATE_CLASS ||
1349 ctx->state == STATE_INTERFACE))
1353 const gchar *deprecated;
1355 name = find_attribute ("name", attribute_names, attribute_values);
1356 value = find_attribute ("value", attribute_names, attribute_values);
1357 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1360 MISSING_ATTRIBUTE (context, error, element_name, "name");
1361 else if (value == NULL)
1362 MISSING_ATTRIBUTE (context, error, element_name, "value");
1365 GIrNodeConstant *constant;
1367 constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
1369 ((GIrNode *)constant)->name = g_strdup (name);
1370 constant->value = g_strdup (value);
1372 ctx->current_typed = (GIrNode*) constant;
1375 constant->deprecated = TRUE;
1377 constant->deprecated = FALSE;
1379 if (ctx->state == STATE_NAMESPACE)
1381 push_node (ctx, (GIrNode *) constant);
1382 ctx->current_module->entries =
1383 g_list_append (ctx->current_module->entries, constant);
1387 GIrNodeInterface *iface;
1389 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1390 iface->members = g_list_append (iface->members, constant);
1395 case STATE_NAMESPACE:
1396 state_switch (ctx, STATE_NAMESPACE_CONSTANT);
1399 state_switch (ctx, STATE_CLASS_CONSTANT);
1401 case STATE_INTERFACE:
1402 state_switch (ctx, STATE_INTERFACE_CONSTANT);
1405 g_assert_not_reached ();
1416 start_errordomain (GMarkupParseContext *context,
1417 const gchar *element_name,
1418 const gchar **attribute_names,
1419 const gchar **attribute_values,
1423 if (strcmp (element_name, "errordomain") == 0 &&
1424 ctx->state == STATE_NAMESPACE)
1427 const gchar *getquark;
1429 const gchar *deprecated;
1431 name = find_attribute ("name", attribute_names, attribute_values);
1432 getquark = find_attribute ("get-quark", attribute_names, attribute_values);
1433 codes = find_attribute ("codes", attribute_names, attribute_values);
1434 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1437 MISSING_ATTRIBUTE (context, error, element_name, "name");
1438 else if (getquark == NULL)
1439 MISSING_ATTRIBUTE (context, error, element_name, "getquark");
1440 else if (codes == NULL)
1441 MISSING_ATTRIBUTE (context, error, element_name, "codes");
1444 GIrNodeErrorDomain *domain;
1446 domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
1448 ((GIrNode *)domain)->name = g_strdup (name);
1449 domain->getquark = g_strdup (getquark);
1450 domain->codes = g_strdup (codes);
1453 domain->deprecated = TRUE;
1455 domain->deprecated = FALSE;
1457 push_node (ctx, (GIrNode *) domain);
1458 ctx->current_module->entries =
1459 g_list_append (ctx->current_module->entries, domain);
1461 state_switch (ctx, STATE_ERRORDOMAIN);
1470 start_interface (GMarkupParseContext *context,
1471 const gchar *element_name,
1472 const gchar **attribute_names,
1473 const gchar **attribute_values,
1477 if (strcmp (element_name, "interface") == 0 &&
1478 ctx->state == STATE_NAMESPACE)
1481 const gchar *typename;
1482 const gchar *typeinit;
1483 const gchar *deprecated;
1485 name = find_attribute ("name", attribute_names, attribute_values);
1486 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1487 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1488 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1491 MISSING_ATTRIBUTE (context, error, element_name, "name");
1492 else if (typename == NULL)
1493 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1494 else if (typeinit == NULL)
1495 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1498 GIrNodeInterface *iface;
1500 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE);
1501 ((GIrNode *)iface)->name = g_strdup (name);
1502 iface->gtype_name = g_strdup (typename);
1503 iface->gtype_init = g_strdup (typeinit);
1505 iface->deprecated = TRUE;
1507 iface->deprecated = FALSE;
1509 push_node (ctx, (GIrNode *) iface);
1510 ctx->current_module->entries =
1511 g_list_append (ctx->current_module->entries, iface);
1513 state_switch (ctx, STATE_INTERFACE);
1523 start_class (GMarkupParseContext *context,
1524 const gchar *element_name,
1525 const gchar **attribute_names,
1526 const gchar **attribute_values,
1530 if (strcmp (element_name, "class") == 0 &&
1531 ctx->state == STATE_NAMESPACE)
1534 const gchar *parent;
1535 const gchar *class_struct;
1536 const gchar *typename;
1537 const gchar *typeinit;
1538 const gchar *deprecated;
1539 const gchar *abstract;
1541 name = find_attribute ("name", attribute_names, attribute_values);
1542 parent = find_attribute ("parent", attribute_names, attribute_values);
1543 class_struct = find_attribute ("glib:class-struct", attribute_names, attribute_values);
1544 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
1545 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
1546 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
1547 abstract = find_attribute ("abstract", attribute_names, attribute_values);
1550 MISSING_ATTRIBUTE (context, error, element_name, "name");
1551 else if (typename == NULL)
1552 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
1553 else if (typeinit == NULL && strcmp (typename, "GObject"))
1554 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
1557 GIrNodeInterface *iface;
1559 iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT);
1560 ((GIrNode *)iface)->name = g_strdup (name);
1561 iface->gtype_name = g_strdup (typename);
1562 iface->gtype_init = g_strdup (typeinit);
1563 iface->parent = g_strdup (parent);
1564 iface->class_struct = g_strdup (class_struct);
1566 iface->deprecated = TRUE;
1568 iface->deprecated = FALSE;
1570 iface->abstract = abstract && strcmp (abstract, "1") == 0;
1572 push_node (ctx, (GIrNode *) iface);
1573 ctx->current_module->entries =
1574 g_list_append (ctx->current_module->entries, iface);
1576 state_switch (ctx, STATE_CLASS);
1585 start_type (GMarkupParseContext *context,
1586 const gchar *element_name,
1587 const gchar **attribute_names,
1588 const gchar **attribute_values,
1595 gboolean is_varargs;
1596 GIrNodeType *typenode;
1598 is_array = strcmp (element_name, "array") == 0;
1599 is_varargs = strcmp (element_name, "varargs") == 0;
1601 if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0)))
1604 if (ctx->state == STATE_TYPE)
1607 ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters);
1608 ctx->type_parameters = NULL;
1610 else if (ctx->state == STATE_FUNCTION_PARAMETER ||
1611 ctx->state == STATE_FUNCTION_RETURN ||
1612 ctx->state == STATE_STRUCT_FIELD ||
1613 ctx->state == STATE_UNION_FIELD ||
1614 ctx->state == STATE_CLASS_PROPERTY ||
1615 ctx->state == STATE_CLASS_FIELD ||
1616 ctx->state == STATE_INTERFACE_FIELD ||
1617 ctx->state == STATE_INTERFACE_PROPERTY ||
1618 ctx->state == STATE_BOXED_FIELD ||
1619 ctx->state == STATE_NAMESPACE_CONSTANT ||
1620 ctx->state == STATE_CLASS_CONSTANT ||
1621 ctx->state == STATE_INTERFACE_CONSTANT
1624 state_switch (ctx, STATE_TYPE);
1625 ctx->type_depth = 1;
1628 switch (CURRENT_NODE (ctx)->type)
1630 case G_IR_NODE_FUNCTION:
1631 case G_IR_NODE_CALLBACK:
1633 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1634 func->is_varargs = TRUE;
1637 case G_IR_NODE_VFUNC:
1639 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1640 vfunc->is_varargs = TRUE;
1643 /* list others individually rather than with default: so that compiler
1644 * warns if new node types are added without adding them to the switch
1646 case G_IR_NODE_INVALID:
1647 case G_IR_NODE_ENUM:
1648 case G_IR_NODE_FLAGS:
1649 case G_IR_NODE_CONSTANT:
1650 case G_IR_NODE_ERROR_DOMAIN:
1651 case G_IR_NODE_PARAM:
1652 case G_IR_NODE_TYPE:
1653 case G_IR_NODE_PROPERTY:
1654 case G_IR_NODE_SIGNAL:
1655 case G_IR_NODE_VALUE:
1656 case G_IR_NODE_FIELD:
1657 case G_IR_NODE_XREF:
1658 case G_IR_NODE_STRUCT:
1659 case G_IR_NODE_BOXED:
1660 case G_IR_NODE_OBJECT:
1661 case G_IR_NODE_INTERFACE:
1662 case G_IR_NODE_UNION:
1663 g_assert_not_reached ();
1667 ctx->type_stack = NULL;
1668 ctx->type_parameters = NULL;
1671 if (!ctx->current_typed)
1675 G_MARKUP_ERROR_INVALID_CONTENT,
1676 "The element <type> is invalid here");
1689 typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE);
1691 typenode->tag = GI_TYPE_TAG_ARRAY;
1692 typenode->is_pointer = TRUE;
1693 typenode->is_array = TRUE;
1695 zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
1696 len = find_attribute ("length", attribute_names, attribute_values);
1697 size = find_attribute ("fixed-size", attribute_names, attribute_values);
1699 typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0);
1700 typenode->has_length = len != NULL;
1701 typenode->length = typenode->has_length ? atoi (len) : -1;
1703 typenode->has_size = size != NULL;
1704 typenode->size = typenode->has_size ? atoi (size) : -1;
1709 name = find_attribute ("name", attribute_names, attribute_values);
1712 MISSING_ATTRIBUTE (context, error, element_name, "name");
1715 ctype = find_attribute ("c:type", attribute_names, attribute_values);
1718 const char *cp = ctype + strlen(ctype) - 1;
1719 while (cp > ctype && *cp-- == '*')
1723 if (ctx->current_typed->type == G_IR_NODE_PARAM &&
1724 ((GIrNodeParam *)ctx->current_typed)->out &&
1728 typenode = parse_type (ctx, name);
1730 /* A 'disguised' structure is one where the c:type is a typedef that
1731 * doesn't look like a pointer, but is internally.
1733 if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
1734 is_disguised_structure (ctx, typenode->interface))
1737 if (pointer_depth > 0)
1738 typenode->is_pointer = TRUE;
1741 ctx->type_parameters = g_list_append (ctx->type_parameters, typenode);
1747 end_type_top (ParseContext *ctx)
1749 GIrNodeType *typenode;
1751 if (!ctx->type_parameters)
1754 typenode = (GIrNodeType*)ctx->type_parameters->data;
1756 /* Default to pointer for unspecified containers */
1757 if (typenode->tag == GI_TYPE_TAG_ARRAY ||
1758 typenode->tag == GI_TYPE_TAG_GLIST ||
1759 typenode->tag == GI_TYPE_TAG_GSLIST)
1761 if (typenode->parameter_type1 == NULL)
1762 typenode->parameter_type1 = parse_type (ctx, "any");
1764 else if (typenode->tag == GI_TYPE_TAG_GHASH)
1766 if (typenode->parameter_type1 == NULL)
1768 typenode->parameter_type1 = parse_type (ctx, "any");
1769 typenode->parameter_type2 = parse_type (ctx, "any");
1773 switch (ctx->current_typed->type)
1775 case G_IR_NODE_PARAM:
1777 GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed;
1778 param->type = typenode;
1781 case G_IR_NODE_FIELD:
1783 GIrNodeField *field = (GIrNodeField *)ctx->current_typed;
1784 field->type = typenode;
1787 case G_IR_NODE_PROPERTY:
1789 GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed;
1790 property->type = typenode;
1793 case G_IR_NODE_CONSTANT:
1795 GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed;
1796 constant->type = typenode;
1800 g_printerr("current node is %d\n", CURRENT_NODE (ctx)->type);
1801 g_assert_not_reached ();
1803 g_list_free (ctx->type_parameters);
1806 ctx->type_depth = 0;
1807 ctx->type_parameters = NULL;
1808 ctx->current_typed = NULL;
1812 end_type_recurse (ParseContext *ctx)
1814 GIrNodeType *parent;
1815 GIrNodeType *param = NULL;
1817 parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data;
1818 if (ctx->type_parameters)
1819 param = (GIrNodeType *) ctx->type_parameters->data;
1821 if (parent->tag == GI_TYPE_TAG_ARRAY ||
1822 parent->tag == GI_TYPE_TAG_GLIST ||
1823 parent->tag == GI_TYPE_TAG_GSLIST)
1825 g_assert (param != NULL);
1827 if (parent->parameter_type1 == NULL)
1828 parent->parameter_type1 = param;
1830 g_assert_not_reached ();
1832 else if (parent->tag == GI_TYPE_TAG_GHASH)
1834 g_assert (param != NULL);
1836 if (parent->parameter_type1 == NULL)
1837 parent->parameter_type1 = param;
1838 else if (parent->parameter_type2 == NULL)
1839 parent->parameter_type2 = param;
1841 g_assert_not_reached ();
1843 g_list_free (ctx->type_parameters);
1844 ctx->type_parameters = (GList *)ctx->type_stack->data;
1845 ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack);
1849 end_type (ParseContext *ctx)
1851 if (ctx->type_depth == 1)
1854 state_switch (ctx, ctx->prev_state);
1858 end_type_recurse (ctx);
1864 start_return_value (GMarkupParseContext *context,
1865 const gchar *element_name,
1866 const gchar **attribute_names,
1867 const gchar **attribute_values,
1871 if (strcmp (element_name, "return-value") == 0 &&
1872 ctx->state == STATE_FUNCTION)
1874 GIrNodeParam *param;
1875 const gchar *transfer;
1877 param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
1880 param->retval = TRUE;
1882 ctx->current_typed = (GIrNode*) param;
1884 state_switch (ctx, STATE_FUNCTION_RETURN);
1886 transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
1887 parse_param_transfer (param, transfer);
1889 switch (CURRENT_NODE (ctx)->type)
1891 case G_IR_NODE_FUNCTION:
1892 case G_IR_NODE_CALLBACK:
1894 GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx);
1895 func->result = param;
1898 case G_IR_NODE_SIGNAL:
1900 GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
1901 signal->result = param;
1904 case G_IR_NODE_VFUNC:
1906 GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
1907 vfunc->result = param;
1911 g_assert_not_reached ();
1921 start_implements (GMarkupParseContext *context,
1922 const gchar *element_name,
1923 const gchar **attribute_names,
1924 const gchar **attribute_values,
1928 GIrNodeInterface *iface;
1931 if (strcmp (element_name, "implements") != 0 ||
1932 !(ctx->state == STATE_CLASS))
1935 state_switch (ctx, STATE_IMPLEMENTS);
1937 name = find_attribute ("name", attribute_names, attribute_values);
1940 MISSING_ATTRIBUTE (context, error, element_name, "name");
1944 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
1945 iface->interfaces = g_list_append (iface->interfaces, g_strdup (name));
1951 start_glib_signal (GMarkupParseContext *context,
1952 const gchar *element_name,
1953 const gchar **attribute_names,
1954 const gchar **attribute_values,
1958 if (strcmp (element_name, "glib:signal") == 0 &&
1959 (ctx->state == STATE_CLASS ||
1960 ctx->state == STATE_INTERFACE))
1964 const gchar *no_recurse;
1965 const gchar *detailed;
1966 const gchar *action;
1967 const gchar *no_hooks;
1968 const gchar *has_class_closure;
1970 name = find_attribute ("name", attribute_names, attribute_values);
1971 when = find_attribute ("when", attribute_names, attribute_values);
1972 no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values);
1973 detailed = find_attribute ("detailed", attribute_names, attribute_values);
1974 action = find_attribute ("action", attribute_names, attribute_values);
1975 no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values);
1976 has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values);
1979 MISSING_ATTRIBUTE (context, error, element_name, "name");
1982 GIrNodeInterface *iface;
1983 GIrNodeSignal *signal;
1985 signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
1987 ((GIrNode *)signal)->name = g_strdup (name);
1989 signal->run_first = FALSE;
1990 signal->run_last = FALSE;
1991 signal->run_cleanup = FALSE;
1992 if (when == NULL || strcmp (when, "LAST") == 0)
1993 signal->run_last = TRUE;
1994 else if (strcmp (when, "FIRST") == 0)
1995 signal->run_first = TRUE;
1997 signal->run_cleanup = TRUE;
1999 if (no_recurse && strcmp (no_recurse, "1") == 0)
2000 signal->no_recurse = TRUE;
2002 signal->no_recurse = FALSE;
2003 if (detailed && strcmp (detailed, "1") == 0)
2004 signal->detailed = TRUE;
2006 signal->detailed = FALSE;
2007 if (action && strcmp (action, "1") == 0)
2008 signal->action = TRUE;
2010 signal->action = FALSE;
2011 if (no_hooks && strcmp (no_hooks, "1") == 0)
2012 signal->no_hooks = TRUE;
2014 signal->no_hooks = FALSE;
2015 if (has_class_closure && strcmp (has_class_closure, "1") == 0)
2016 signal->has_class_closure = TRUE;
2018 signal->has_class_closure = FALSE;
2020 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2021 iface->members = g_list_append (iface->members, signal);
2023 push_node (ctx, (GIrNode *)signal);
2024 state_switch (ctx, STATE_FUNCTION);
2033 start_vfunc (GMarkupParseContext *context,
2034 const gchar *element_name,
2035 const gchar **attribute_names,
2036 const gchar **attribute_values,
2040 if (strcmp (element_name, "vfunc") == 0 &&
2041 (ctx->state == STATE_CLASS ||
2042 ctx->state == STATE_INTERFACE))
2045 const gchar *must_chain_up;
2046 const gchar *override;
2047 const gchar *is_class_closure;
2048 const gchar *offset;
2050 name = find_attribute ("name", attribute_names, attribute_values);
2051 must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values);
2052 override = find_attribute ("override", attribute_names, attribute_values);
2053 is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values);
2054 offset = find_attribute ("offset", attribute_names, attribute_values);
2057 MISSING_ATTRIBUTE (context, error, element_name, "name");
2060 GIrNodeInterface *iface;
2061 GIrNodeVFunc *vfunc;
2063 vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
2065 ((GIrNode *)vfunc)->name = g_strdup (name);
2067 if (must_chain_up && strcmp (must_chain_up, "1") == 0)
2068 vfunc->must_chain_up = TRUE;
2070 vfunc->must_chain_up = FALSE;
2072 if (override && strcmp (override, "always") == 0)
2074 vfunc->must_be_implemented = TRUE;
2075 vfunc->must_not_be_implemented = FALSE;
2077 else if (override && strcmp (override, "never") == 0)
2079 vfunc->must_be_implemented = FALSE;
2080 vfunc->must_not_be_implemented = TRUE;
2084 vfunc->must_be_implemented = FALSE;
2085 vfunc->must_not_be_implemented = FALSE;
2088 if (is_class_closure && strcmp (is_class_closure, "1") == 0)
2089 vfunc->is_class_closure = TRUE;
2091 vfunc->is_class_closure = FALSE;
2094 vfunc->offset = atoi (offset);
2098 iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
2099 iface->members = g_list_append (iface->members, vfunc);
2101 push_node (ctx, (GIrNode *)vfunc);
2102 state_switch (ctx, STATE_FUNCTION);
2112 start_struct (GMarkupParseContext *context,
2113 const gchar *element_name,
2114 const gchar **attribute_names,
2115 const gchar **attribute_values,
2119 if (strcmp (element_name, "record") == 0 &&
2120 (ctx->state == STATE_NAMESPACE ||
2121 ctx->state == STATE_UNION ||
2122 ctx->state == STATE_STRUCT ||
2123 ctx->state == STATE_CLASS))
2126 const gchar *deprecated;
2127 const gchar *disguised;
2128 const gchar *gtype_name;
2129 const gchar *gtype_init;
2130 const gchar *gclass_struct;
2131 GIrNodeStruct *struct_;
2133 name = find_attribute ("name", attribute_names, attribute_values);
2134 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2135 disguised = find_attribute ("disguised", attribute_names, attribute_values);
2136 gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
2137 gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
2138 gclass_struct = find_attribute ("glib:is-class-struct-for", attribute_names, attribute_values);
2140 if (name == NULL && ctx->node_stack == NULL)
2142 MISSING_ATTRIBUTE (context, error, element_name, "name");
2145 if ((gtype_name == NULL && gtype_init != NULL))
2147 MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
2150 if ((gtype_name != NULL && gtype_init == NULL))
2152 MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
2156 struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
2158 ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
2160 struct_->deprecated = TRUE;
2162 struct_->deprecated = FALSE;
2164 if (disguised && strcmp (disguised, "1") == 0)
2165 struct_->disguised = TRUE;
2167 struct_->is_gclass_struct = gclass_struct != NULL;
2169 struct_->gtype_name = g_strdup (gtype_name);
2170 struct_->gtype_init = g_strdup (gtype_init);
2172 if (ctx->node_stack == NULL)
2173 ctx->current_module->entries =
2174 g_list_append (ctx->current_module->entries, struct_);
2175 push_node (ctx, (GIrNode *)struct_);
2177 state_switch (ctx, STATE_STRUCT);
2185 start_union (GMarkupParseContext *context,
2186 const gchar *element_name,
2187 const gchar **attribute_names,
2188 const gchar **attribute_values,
2192 if (strcmp (element_name, "union") == 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 *typename;
2201 const gchar *typeinit;
2203 name = find_attribute ("name", attribute_names, attribute_values);
2204 deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
2205 typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
2206 typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
2208 if (name == NULL && ctx->node_stack == NULL)
2209 MISSING_ATTRIBUTE (context, error, element_name, "name");
2212 GIrNodeUnion *union_;
2214 union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
2216 ((GIrNode *)union_)->name = g_strdup (name ? name : "");
2217 union_->gtype_name = g_strdup (typename);
2218 union_->gtype_init = g_strdup (typeinit);
2220 union_->deprecated = TRUE;
2222 union_->deprecated = FALSE;
2224 if (ctx->node_stack == NULL)
2225 ctx->current_module->entries =
2226 g_list_append (ctx->current_module->entries, union_);
2227 push_node (ctx, (GIrNode *)union_);
2229 state_switch (ctx, STATE_UNION);
2237 start_discriminator (GMarkupParseContext *context,
2238 const gchar *element_name,
2239 const gchar **attribute_names,
2240 const gchar **attribute_values,
2244 if (strcmp (element_name, "discriminator") == 0 &&
2245 ctx->state == STATE_UNION)
2248 const gchar *offset;
2250 type = find_attribute ("type", attribute_names, attribute_values);
2251 offset = find_attribute ("offset", attribute_names, attribute_values);
2253 MISSING_ATTRIBUTE (context, error, element_name, "type");
2254 else if (offset == NULL)
2255 MISSING_ATTRIBUTE (context, error, element_name, "offset");
2257 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type
2258 = parse_type (ctx, type);
2259 ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset
2270 parse_include (GMarkupParseContext *context,
2273 const char *version,
2279 gboolean success = FALSE;
2283 for (l = ctx->parser->parsed_modules; l; l = l->next)
2285 GIrModule *m = l->data;
2287 if (strcmp (m->name, name) == 0)
2289 if (strcmp (m->version, version) == 0)
2291 ctx->include_modules = g_list_prepend (ctx->include_modules, m);
2299 G_MARKUP_ERROR_INVALID_CONTENT,
2300 "Module '%s' imported with conflicting versions '%s' and '%s'",
2301 name, m->version, version);
2307 girpath = locate_gir (ctx->parser, name, version);
2309 if (girpath == NULL)
2313 G_MARKUP_ERROR_INVALID_CONTENT,
2314 "Could not find GIR file '%s.gir'; check XDG_DATA_DIRS or use --includedir",
2319 g_debug ("Parsing include %s", girpath);
2321 if (!g_file_get_contents (girpath, &buffer, &length, error))
2328 modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error);
2329 success = error != NULL;
2331 ctx->include_modules = g_list_concat (ctx->include_modules,
2339 extern GLogLevelFlags logged_levels;
2342 start_element_handler (GMarkupParseContext *context,
2343 const gchar *element_name,
2344 const gchar **attribute_names,
2345 const gchar **attribute_values,
2349 ParseContext *ctx = user_data;
2350 gint line_number, char_number;
2352 if (logged_levels & G_LOG_LEVEL_DEBUG)
2354 GString *tags = g_string_new ("");
2356 for (i = 0; attribute_names[i]; i++)
2357 g_string_append_printf (tags, "%s=\"%s\" ",
2359 attribute_values[i]);
2363 g_string_insert_c (tags, 0, ' ');
2364 g_string_truncate (tags, tags->len - 1);
2366 g_debug ("<%s%s>", element_name, tags->str);
2367 g_string_free (tags, TRUE);
2370 switch (element_name[0])
2373 if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0)
2375 state_switch (ctx, STATE_ALIAS);
2378 if (start_type (context, element_name,
2379 attribute_names, attribute_values,
2384 if (start_enum (context, element_name,
2385 attribute_names, attribute_values,
2390 if (start_function (context, element_name,
2391 attribute_names, attribute_values,
2394 else if (start_constant (context, element_name,
2395 attribute_names, attribute_values,
2398 else if (start_class (context, element_name,
2399 attribute_names, attribute_values,
2405 if (start_discriminator (context, element_name,
2406 attribute_names, attribute_values,
2412 if (start_enum (context, element_name,
2413 attribute_names, attribute_values,
2416 else if (start_errordomain (context, element_name,
2417 attribute_names, attribute_values,
2423 if (start_function (context, element_name,
2424 attribute_names, attribute_values,
2427 else if (start_field (context, element_name,
2428 attribute_names, attribute_values,
2434 if (start_glib_boxed (context, element_name,
2435 attribute_names, attribute_values,
2438 else if (start_glib_signal (context, element_name,
2439 attribute_names, attribute_values,
2445 if (strcmp (element_name, "include") == 0 &&
2446 ctx->state == STATE_REPOSITORY)
2449 const gchar *version;
2451 name = find_attribute ("name", attribute_names, attribute_values);
2452 version = find_attribute ("version", attribute_names, attribute_values);
2456 MISSING_ATTRIBUTE (context, error, element_name, "name");
2459 if (version == NULL)
2461 MISSING_ATTRIBUTE (context, error, element_name, "version");
2465 if (!parse_include (context, ctx, name, version, error))
2468 ctx->dependencies = g_list_prepend (ctx->dependencies,
2469 g_strdup_printf ("%s-%s", name, version));
2472 state_switch (ctx, STATE_INCLUDE);
2475 if (start_interface (context, element_name,
2476 attribute_names, attribute_values,
2479 else if (start_implements (context, element_name,
2480 attribute_names, attribute_values,
2486 if (start_function (context, element_name,
2487 attribute_names, attribute_values,
2490 else if (start_member (context, element_name,
2491 attribute_names, attribute_values,
2497 if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY)
2499 const gchar *name, *version, *shared_library;
2501 if (ctx->current_module != NULL)
2505 G_MARKUP_ERROR_INVALID_CONTENT,
2506 "Only one <namespace/> element is currently allowed per <repository/>");
2510 name = find_attribute ("name", attribute_names, attribute_values);
2511 version = find_attribute ("version", attribute_names, attribute_values);
2512 shared_library = find_attribute ("shared-library", attribute_names, attribute_values);
2515 MISSING_ATTRIBUTE (context, error, element_name, "name");
2516 else if (version == NULL)
2517 MISSING_ATTRIBUTE (context, error, element_name, "version");
2522 if (strcmp (name, ctx->namespace) != 0)
2525 G_MARKUP_ERROR_INVALID_CONTENT,
2526 "<namespace/> name element '%s' doesn't match file name '%s'",
2527 name, ctx->namespace);
2529 ctx->current_module = g_ir_module_new (name, version, shared_library);
2531 ctx->current_module->aliases = ctx->aliases;
2532 ctx->aliases = NULL;
2533 ctx->current_module->disguised_structures = ctx->disguised_structures;
2534 ctx->disguised_structures = NULL;
2536 for (l = ctx->include_modules; l; l = l->next)
2537 g_ir_module_add_include_module (ctx->current_module, l->data);
2539 g_list_free (ctx->include_modules);
2540 ctx->include_modules = NULL;
2542 ctx->modules = g_list_append (ctx->modules, ctx->current_module);
2543 ctx->current_module->dependencies = ctx->dependencies;
2545 state_switch (ctx, STATE_NAMESPACE);
2552 if (start_property (context, element_name,
2553 attribute_names, attribute_values,
2556 else if (strcmp (element_name, "parameters") == 0 &&
2557 ctx->state == STATE_FUNCTION)
2559 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2563 else if (start_parameter (context, element_name,
2564 attribute_names, attribute_values,
2567 else if (strcmp (element_name, "prerequisite") == 0 &&
2568 ctx->state == STATE_INTERFACE)
2572 name = find_attribute ("name", attribute_names, attribute_values);
2574 state_switch (ctx, STATE_PREREQUISITE);
2577 MISSING_ATTRIBUTE (context, error, element_name, "name");
2580 GIrNodeInterface *iface;
2582 iface = (GIrNodeInterface *)CURRENT_NODE(ctx);
2583 iface->prerequisites = g_list_append (iface->prerequisites, g_strdup (name));
2590 if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START)
2592 const gchar *version;
2594 version = find_attribute ("version", attribute_names, attribute_values);
2596 if (version == NULL)
2597 MISSING_ATTRIBUTE (context, error, element_name, "version");
2598 else if (strcmp (version, "1.0") != 0)
2601 G_MARKUP_ERROR_INVALID_CONTENT,
2602 "Unsupported version '%s'",
2605 state_switch (ctx, STATE_REPOSITORY);
2609 else if (start_return_value (context, element_name,
2610 attribute_names, attribute_values,
2613 else if (start_struct (context, element_name,
2614 attribute_names, attribute_values,
2620 if (start_union (context, element_name,
2621 attribute_names, attribute_values,
2627 if (start_type (context, element_name,
2628 attribute_names, attribute_values,
2634 if (start_vfunc (context, element_name,
2635 attribute_names, attribute_values,
2638 if (start_type (context, element_name,
2639 attribute_names, attribute_values,
2645 if (ctx->state != STATE_UNKNOWN)
2647 state_switch (ctx, STATE_UNKNOWN);
2648 ctx->unknown_depth = 1;
2652 ctx->unknown_depth += 1;
2658 g_markup_parse_context_get_position (context, &line_number, &char_number);
2660 fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message);
2661 backtrace_stderr ();
2666 require_one_of_end_elements (GMarkupParseContext *context,
2668 const char *actual_name,
2673 int line_number, char_number;
2674 const char *expected;
2675 gboolean matched = FALSE;
2677 va_start (args, error);
2679 while ((expected = va_arg (args, const char*)) != NULL)
2681 if (strcmp (expected, actual_name) == 0)
2693 g_markup_parse_context_get_position (context, &line_number, &char_number);
2696 G_MARKUP_ERROR_INVALID_CONTENT,
2697 "Unexpected end tag '%s' on line %d char %d; current state=%d",
2699 line_number, char_number, ctx->state);
2705 state_switch_end_struct_or_union (GMarkupParseContext *context,
2707 const gchar *element_name,
2711 if (ctx->node_stack == NULL)
2713 state_switch (ctx, STATE_NAMESPACE);
2717 if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2718 state_switch (ctx, STATE_STRUCT);
2719 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2720 state_switch (ctx, STATE_UNION);
2721 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2722 state_switch (ctx, STATE_CLASS);
2725 int line_number, char_number;
2726 g_markup_parse_context_get_position (context, &line_number, &char_number);
2729 G_MARKUP_ERROR_INVALID_CONTENT,
2730 "Unexpected end tag '%s' on line %d char %d",
2732 line_number, char_number);
2740 require_end_element (GMarkupParseContext *context,
2742 const char *expected_name,
2743 const char *actual_name,
2746 return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL);
2750 end_element_handler (GMarkupParseContext *context,
2751 const gchar *element_name,
2755 ParseContext *ctx = user_data;
2757 g_debug ("</%s>", element_name);
2763 /* no need to GError here, GMarkup already catches this */
2766 case STATE_REPOSITORY:
2767 state_switch (ctx, STATE_END);
2771 if (require_end_element (context, ctx, "include", element_name, error))
2773 state_switch (ctx, STATE_REPOSITORY);
2777 case STATE_NAMESPACE:
2778 if (require_end_element (context, ctx, "namespace", element_name, error))
2780 ctx->current_module = NULL;
2781 state_switch (ctx, STATE_REPOSITORY);
2786 if (require_end_element (context, ctx, "alias", element_name, error))
2788 state_switch (ctx, STATE_NAMESPACE);
2792 case STATE_FUNCTION_RETURN:
2793 if (strcmp ("type", element_name) == 0)
2795 if (require_end_element (context, ctx, "return-value", element_name, error))
2797 state_switch (ctx, STATE_FUNCTION);
2801 case STATE_FUNCTION_PARAMETERS:
2802 if (require_end_element (context, ctx, "parameters", element_name, error))
2804 state_switch (ctx, STATE_FUNCTION);
2808 case STATE_FUNCTION_PARAMETER:
2809 if (strcmp ("type", element_name) == 0)
2811 if (require_end_element (context, ctx, "parameter", element_name, error))
2813 state_switch (ctx, STATE_FUNCTION_PARAMETERS);
2817 case STATE_FUNCTION:
2820 if (ctx->node_stack == NULL)
2822 state_switch (ctx, STATE_NAMESPACE);
2826 if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE)
2827 state_switch (ctx, STATE_INTERFACE);
2828 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT)
2829 state_switch (ctx, STATE_CLASS);
2830 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_BOXED)
2831 state_switch (ctx, STATE_BOXED);
2832 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT)
2833 state_switch (ctx, STATE_STRUCT);
2834 else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION)
2835 state_switch (ctx, STATE_UNION);
2838 int line_number, char_number;
2839 g_markup_parse_context_get_position (context, &line_number, &char_number);
2842 G_MARKUP_ERROR_INVALID_CONTENT,
2843 "Unexpected end tag '%s' on line %d char %d",
2845 line_number, char_number);
2851 case STATE_CLASS_FIELD:
2852 if (strcmp ("type", element_name) == 0)
2854 if (require_end_element (context, ctx, "field", element_name, error))
2856 state_switch (ctx, STATE_CLASS);
2860 case STATE_CLASS_PROPERTY:
2861 if (strcmp ("type", element_name) == 0)
2863 if (require_end_element (context, ctx, "property", element_name, error))
2865 state_switch (ctx, STATE_CLASS);
2870 if (require_end_element (context, ctx, "class", element_name, error))
2873 state_switch (ctx, STATE_NAMESPACE);
2877 case STATE_ERRORDOMAIN:
2878 if (require_end_element (context, ctx, "errordomain", element_name, error))
2881 state_switch (ctx, STATE_NAMESPACE);
2885 case STATE_INTERFACE_PROPERTY:
2886 if (strcmp ("type", element_name) == 0)
2888 if (require_end_element (context, ctx, "property", element_name, error))
2890 state_switch (ctx, STATE_INTERFACE);
2894 case STATE_INTERFACE_FIELD:
2895 if (strcmp ("type", element_name) == 0)
2897 if (require_end_element (context, ctx, "field", element_name, error))
2899 state_switch (ctx, STATE_INTERFACE);
2903 case STATE_INTERFACE:
2904 if (require_end_element (context, ctx, "interface", element_name, error))
2907 state_switch (ctx, STATE_NAMESPACE);
2912 if (strcmp ("member", element_name) == 0)
2914 else if (require_one_of_end_elements (context, ctx,
2915 element_name, error, "enumeration",
2919 state_switch (ctx, STATE_NAMESPACE);
2924 if (require_end_element (context, ctx, "glib:boxed", element_name, error))
2927 state_switch (ctx, STATE_NAMESPACE);
2931 case STATE_BOXED_FIELD:
2932 if (strcmp ("type", element_name) == 0)
2934 if (require_end_element (context, ctx, "field", element_name, error))
2936 state_switch (ctx, STATE_BOXED);
2940 case STATE_STRUCT_FIELD:
2941 if (strcmp ("type", element_name) == 0)
2943 if (require_end_element (context, ctx, "field", element_name, error))
2945 state_switch (ctx, STATE_STRUCT);
2950 if (require_end_element (context, ctx, "record", element_name, error))
2952 state_switch_end_struct_or_union (context, ctx, element_name, error);
2956 case STATE_UNION_FIELD:
2957 if (strcmp ("type", element_name) == 0)
2959 if (require_end_element (context, ctx, "field", element_name, error))
2961 state_switch (ctx, STATE_UNION);
2966 if (require_end_element (context, ctx, "union", element_name, error))
2968 state_switch_end_struct_or_union (context, ctx, element_name, error);
2971 case STATE_IMPLEMENTS:
2972 if (strcmp ("interface", element_name) == 0)
2974 if (require_end_element (context, ctx, "implements", element_name, error))
2975 state_switch (ctx, STATE_CLASS);
2977 case STATE_PREREQUISITE:
2978 if (require_end_element (context, ctx, "prerequisite", element_name, error))
2979 state_switch (ctx, STATE_INTERFACE);
2981 case STATE_NAMESPACE_CONSTANT:
2982 case STATE_CLASS_CONSTANT:
2983 case STATE_INTERFACE_CONSTANT:
2984 if (strcmp ("type", element_name) == 0)
2986 if (require_end_element (context, ctx, "constant", element_name, error))
2991 case STATE_NAMESPACE_CONSTANT:
2992 state_switch (ctx, STATE_NAMESPACE);
2994 case STATE_CLASS_CONSTANT:
2995 state_switch (ctx, STATE_CLASS);
2997 case STATE_INTERFACE_CONSTANT:
2998 state_switch (ctx, STATE_INTERFACE);
3001 g_assert_not_reached ();
3007 if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) ||
3008 (strcmp ("varargs", element_name) == 0))
3014 ctx->unknown_depth -= 1;
3015 if (ctx->unknown_depth == 0)
3016 state_switch (ctx, ctx->prev_state);
3019 g_error ("Unhandled state %d in end_element_handler\n", ctx->state);
3024 text_handler (GMarkupParseContext *context,
3030 /* FIXME warn about non-whitespace text */
3034 cleanup (GMarkupParseContext *context,
3038 ParseContext *ctx = user_data;
3041 for (m = ctx->modules; m; m = m->next)
3042 g_ir_module_free (m->data);
3043 g_list_free (ctx->modules);
3044 ctx->modules = NULL;
3046 ctx->current_module = NULL;
3050 post_filter_toplevel_varargs_functions (GList *list,
3051 GList **varargs_callbacks_out)
3054 GList *varargs_callbacks = *varargs_callbacks_out;
3060 GIrNode *node = iter->data;
3064 if (node->type == G_IR_NODE_FUNCTION)
3066 if (((GIrNodeFunction*)node)->is_varargs)
3068 list = g_list_delete_link (list, link);
3071 if (node->type == G_IR_NODE_CALLBACK)
3073 if (((GIrNodeFunction*)node)->is_varargs)
3075 varargs_callbacks = g_list_append (varargs_callbacks,
3077 list = g_list_delete_link (list, link);
3082 *varargs_callbacks_out = varargs_callbacks;
3088 post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out)
3091 GList *varargs_callbacks;
3093 list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out);
3095 varargs_callbacks = *varargs_callbacks_out;
3101 GIrNode *node = iter->data;
3105 if (node->type == G_IR_NODE_FUNCTION)
3108 gboolean function_done = FALSE;
3110 for (param = ((GIrNodeFunction *)node)->parameters;
3112 param = param->next)
3114 GIrNodeParam *node = (GIrNodeParam *)param->data;
3119 if (node->type->is_interface)
3122 for (callback = varargs_callbacks;
3124 callback = callback->next)
3126 if (!strcmp (node->type->interface,
3127 ((GIrNode *)varargs_callbacks->data)->name))
3129 list = g_list_delete_link (list, link);
3130 function_done = TRUE;
3139 *varargs_callbacks_out = varargs_callbacks;
3145 post_filter (GIrModule *module)
3148 GList *varargs_callbacks = NULL;
3150 module->entries = post_filter_varargs_functions (module->entries,
3151 &varargs_callbacks);
3152 iter = module->entries;
3155 GIrNode *node = iter->data;
3159 if (node->type == G_IR_NODE_OBJECT ||
3160 node->type == G_IR_NODE_INTERFACE)
3162 GIrNodeInterface *iface = (GIrNodeInterface*)node;
3163 iface->members = post_filter_varargs_functions (iface->members,
3164 &varargs_callbacks);
3166 else if (node->type == G_IR_NODE_BOXED)
3168 GIrNodeBoxed *boxed = (GIrNodeBoxed*)node;
3169 boxed->members = post_filter_varargs_functions (boxed->members,
3170 &varargs_callbacks);
3172 else if (node->type == G_IR_NODE_STRUCT)
3174 GIrNodeStruct *iface = (GIrNodeStruct*)node;
3175 iface->members = post_filter_varargs_functions (iface->members,
3176 &varargs_callbacks);
3178 else if (node->type == G_IR_NODE_UNION)
3180 GIrNodeUnion *iface = (GIrNodeUnion*)node;
3181 iface->members = post_filter_varargs_functions (iface->members,
3182 &varargs_callbacks);
3185 g_list_free (varargs_callbacks);
3189 * g_ir_parser_parse_string:
3190 * @parser: a #GIrParser
3191 * @namespace: the namespace of the string
3192 * @buffer: the data containing the XML
3193 * @length: length of the data
3194 * @error: return location for a #GError, or %NULL
3196 * Parse a string that holds a complete GIR XML file, and return a list of a
3197 * a #GirModule for each <namespace/> element within the file.
3199 * Returns: a newly allocated list of #GIrModule. The modules themselves
3200 * are owned by the #GIrParser and will be freed along with the parser.
3203 g_ir_parser_parse_string (GIrParser *parser,
3204 const gchar *namespace,
3205 const gchar *buffer,
3209 ParseContext ctx = { 0 };
3210 GMarkupParseContext *context;
3212 ctx.parser = parser;
3213 ctx.state = STATE_START;
3214 ctx.namespace = namespace;
3215 ctx.include_modules = NULL;
3216 ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
3217 ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
3219 ctx.dependencies = NULL;
3220 ctx.current_module = NULL;
3222 context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL);
3224 if (!g_markup_parse_context_parse (context, buffer, length, error))
3227 if (!g_markup_parse_context_end_parse (context, error))
3230 g_markup_parse_context_free (context);
3232 context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL);
3233 if (!g_markup_parse_context_parse (context, buffer, length, error))
3236 if (!g_markup_parse_context_end_parse (context, error))
3239 parser->parsed_modules = g_list_concat (g_list_copy (ctx.modules),
3240 parser->parsed_modules);
3244 if (ctx.modules == NULL)
3246 /* An error occurred before we created a module, so we haven't
3247 * transferred ownership of these hash tables to the module.
3249 if (ctx.aliases != NULL)
3250 g_hash_table_destroy (ctx.aliases);
3251 if (ctx.disguised_structures != NULL)
3252 g_hash_table_destroy (ctx.disguised_structures);
3253 g_list_free (ctx.include_modules);
3256 g_markup_parse_context_free (context);
3262 * g_ir_parser_parse_file:
3263 * @parser: a #GIrParser
3264 * @filename: filename to parse
3265 * @error: return location for a #GError, or %NULL
3267 * Parse GIR XML file, and return a list of a a #GirModule for each
3268 * <namespace/> element within the file.
3270 * Returns: a newly allocated list of #GIrModule. The modules themselves
3271 * are owned by the #GIrParser and will be freed along with the parser.
3274 g_ir_parser_parse_file (GIrParser *parser,
3275 const gchar *filename,
3286 if (!g_str_has_suffix (filename, ".gir"))
3290 G_MARKUP_ERROR_INVALID_CONTENT,
3291 "Expected filename to end with '.gir'");
3295 g_debug ("[parsing] filename %s", filename);
3297 slash = g_strrstr (filename, "/");
3299 namespace = g_strdup (filename);
3301 namespace = g_strdup (slash+1);
3302 namespace[strlen(namespace)-4] = '\0';
3304 /* Remove version */
3305 dash = strstr (namespace, "-");
3309 if (!g_file_get_contents (filename, &buffer, &length, error))
3312 modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error);
3314 for (iter = modules; iter; iter = iter->next)
3316 post_filter ((GIrModule*)iter->data);