1 /* GObject introspection: A parser for the XML IDL format
3 * Copyright (C) 2005 Matthias Clasen
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 "gidlmodule.h"
28 #include "gmetadata.h"
50 typedef struct _ParseContext ParseContext
;
54 ParseState prev_state
;
58 GIdlModule
*current_module
;
59 GIdlNode
*current_node
;
62 #define MISSING_ATTRIBUTE(error,element,attribute) \
65 G_MARKUP_ERROR_INVALID_CONTENT, \
66 "The attribute '%s' on the element '%s' must be specified", \
70 find_attribute (const gchar
*name
,
71 const gchar
**attribute_names
,
72 const gchar
**attribute_values
)
76 for (i
= 0; attribute_names
[i
] != NULL
; i
++)
77 if (strcmp (attribute_names
[i
], name
) == 0)
78 return attribute_values
[i
];
84 parse_type_internal (gchar
*str
, gchar
**rest
)
93 { "void", TYPE_TAG_VOID
, 0 },
94 { "gpointer", TYPE_TAG_VOID
, 1 },
95 { "bool", TYPE_TAG_BOOLEAN
, 0 },
96 { "gboolean", TYPE_TAG_BOOLEAN
, 0 },
98 { "char", TYPE_TAG_INT8
, 0 },
99 { "gchar", TYPE_TAG_INT8
, 0 },
100 { "guchar", TYPE_TAG_UINT8
, 0 },
102 { "int8_t", TYPE_TAG_INT8
, 0 },
103 { "int8", TYPE_TAG_INT8
, 0 },
104 { "gint8", TYPE_TAG_INT8
, 0 },
105 { "uint8_t", TYPE_TAG_UINT8
, 0 },
106 { "uint8", TYPE_TAG_UINT8
, 0 },
107 { "guint8", TYPE_TAG_UINT8
, 0 },
108 { "int16_t", TYPE_TAG_INT16
, 0 },
109 { "int16", TYPE_TAG_INT16
, 0 },
110 { "gint16", TYPE_TAG_INT16
, 0 },
111 { "uint16_t", TYPE_TAG_UINT16
, 0 },
112 { "uint16", TYPE_TAG_UINT16
, 0 },
113 { "guint16", TYPE_TAG_UINT16
, 0 },
114 { "int32_t", TYPE_TAG_INT32
, 0 },
115 { "int32", TYPE_TAG_INT32
, 0 },
116 { "gint32", TYPE_TAG_INT32
, 0 },
117 { "uint32_t", TYPE_TAG_UINT32
, 0 },
118 { "uint32", TYPE_TAG_UINT32
, 0 },
119 { "guint32", TYPE_TAG_UINT32
, 0 },
120 { "int64_t", TYPE_TAG_INT64
, 0 },
121 { "int64", TYPE_TAG_INT64
, 0 },
122 { "gint64", TYPE_TAG_INT64
, 0 },
123 { "uint64_t", TYPE_TAG_UINT64
, 0 },
124 { "uint64", TYPE_TAG_UINT64
, 0 },
125 { "guint64", TYPE_TAG_UINT64
, 0 },
126 { "int", TYPE_TAG_INT
, 0 },
127 { "gint", TYPE_TAG_INT
, 0 },
128 { "uint", TYPE_TAG_UINT
, 0 },
129 { "guint", TYPE_TAG_UINT
, 0 },
130 { "long", TYPE_TAG_LONG
, 0 },
131 { "glong", TYPE_TAG_LONG
, 0 },
132 { "ulong", TYPE_TAG_ULONG
, 0 },
133 { "gulong", TYPE_TAG_ULONG
, 0 },
134 { "ssize_t", TYPE_TAG_SSIZE
, 0 },
135 { "gssize", TYPE_TAG_SSIZE
, 0 },
136 { "size_t", TYPE_TAG_SIZE
, 0 },
137 { "gsize", TYPE_TAG_SIZE
, 0 },
138 { "float", TYPE_TAG_FLOAT
, 0 },
139 { "gfloat", TYPE_TAG_FLOAT
, 0 },
140 { "double", TYPE_TAG_DOUBLE
, 0 },
141 { "gdouble", TYPE_TAG_DOUBLE
, 0 },
142 { "utf8", TYPE_TAG_UTF8
, 1 },
143 { "gchar*", TYPE_TAG_UTF8
, 1 },
144 { "filename", TYPE_TAG_FILENAME
,1 }
147 gint n_basic
= G_N_ELEMENTS (basic
);
152 type
= (GIdlNodeType
*)g_idl_node_new (G_IDL_NODE_TYPE
);
154 str
= g_strstrip (str
);
156 type
->unparsed
= g_strdup (str
);
159 for (i
= 0; i
< n_basic
; i
++)
161 if (g_str_has_prefix (*rest
, basic
[i
].str
))
163 type
->is_basic
= TRUE
;
164 type
->tag
= basic
[i
].tag
;
165 type
->is_pointer
= basic
[i
].pointer
;
167 *rest
+= strlen(basic
[i
].str
);
168 *rest
= g_strchug (*rest
);
169 if (**rest
== '*' && !type
->is_pointer
)
171 type
->is_pointer
= TRUE
;
180 /* found a basic type */;
181 else if (g_str_has_prefix (*rest
, "GList") ||
182 g_str_has_prefix (*rest
, "GSList"))
184 if (g_str_has_prefix (*rest
, "GList"))
186 type
->tag
= TYPE_TAG_LIST
;
187 type
->is_glist
= TRUE
;
188 type
->is_pointer
= TRUE
;
189 *rest
+= strlen ("GList");
193 type
->tag
= TYPE_TAG_SLIST
;
194 type
->is_gslist
= TRUE
;
195 type
->is_pointer
= TRUE
;
196 *rest
+= strlen ("GSList");
199 *rest
= g_strchug (*rest
);
205 type
->parameter_type1
= parse_type_internal (*rest
, rest
);
206 if (type
->parameter_type1
== NULL
)
209 *rest
= g_strchug (*rest
);
211 if ((*rest
)[0] != '>')
216 else if (g_str_has_prefix (*rest
, "GHashTable"))
218 type
->tag
= TYPE_TAG_HASH
;
219 type
->is_ghashtable
= TRUE
;
220 type
->is_pointer
= TRUE
;
221 *rest
+= strlen ("GHashTable");
223 *rest
= g_strchug (*rest
);
229 type
->parameter_type1
= parse_type_internal (*rest
, rest
);
230 if (type
->parameter_type1
== NULL
)
233 *rest
= g_strchug (*rest
);
235 if ((*rest
)[0] != ',')
239 type
->parameter_type2
= parse_type_internal (*rest
, rest
);
240 if (type
->parameter_type2
== NULL
)
243 if ((*rest
)[0] != '>')
248 else if (g_str_has_prefix (*rest
, "GError"))
250 type
->tag
= TYPE_TAG_ERROR
;
251 type
->is_error
= TRUE
;
252 type
->is_pointer
= TRUE
;
253 *rest
+= strlen ("GError");
255 *rest
= g_strchug (*rest
);
261 end
= strchr (*rest
, '>');
262 str
= g_strndup (*rest
, end
- *rest
);
263 type
->errors
= g_strsplit (str
, ",", 0);
271 type
->tag
= TYPE_TAG_INTERFACE
;
272 type
->is_interface
= TRUE
;
275 /* must be an interface type */
276 while (g_ascii_isalnum (**rest
) ||
283 type
->interface
= g_strndup (start
, *rest
- start
);
285 *rest
= g_strchug (*rest
);
288 type
->is_pointer
= TRUE
;
293 *rest
= g_strchug (*rest
);
294 if (g_str_has_prefix (*rest
, "["))
298 array
= (GIdlNodeType
*)g_idl_node_new (G_IDL_NODE_TYPE
);
300 array
->tag
= TYPE_TAG_ARRAY
;
301 array
->is_pointer
= TRUE
;
302 array
->is_array
= TRUE
;
304 array
->parameter_type1
= type
;
306 array
->zero_terminated
= FALSE
;
307 array
->has_length
= FALSE
;
310 if (!g_str_has_prefix (*rest
, "[]"))
312 gchar
*end
, *str
, **opts
;
314 end
= strchr (*rest
, ']');
315 str
= g_strndup (*rest
+ 1, (end
- *rest
) - 1);
316 opts
= g_strsplit (str
, ",", 0);
320 for (i
= 0; opts
[i
]; i
++)
324 vals
= g_strsplit (opts
[i
], "=", 0);
326 if (strcmp (vals
[0], "zero-terminated") == 0)
327 array
->zero_terminated
= (strcmp (vals
[1], "1") == 0);
328 else if (strcmp (vals
[0], "length") == 0)
330 array
->has_length
= TRUE
;
331 array
->length
= atoi (vals
[1]);
347 g_idl_node_free ((GIdlNode
*)type
);
352 static GIdlNodeType
*
353 parse_type (const gchar
*type
)
359 str
= g_strdup (type
);
360 node
= parse_type_internal (str
, &rest
);
367 start_boxed (GMarkupParseContext
*context
,
368 const gchar
*element_name
,
369 const gchar
**attribute_names
,
370 const gchar
**attribute_values
,
374 if (strcmp (element_name
, "boxed") == 0 &&
375 ctx
->state
== STATE_NAMESPACE
)
378 const gchar
*typename
;
379 const gchar
*typeinit
;
380 const gchar
*deprecated
;
382 name
= find_attribute ("name", attribute_names
, attribute_values
);
383 typename
= find_attribute ("type-name", attribute_names
, attribute_values
);
384 typeinit
= find_attribute ("get-type", attribute_names
, attribute_values
);
385 deprecated
= find_attribute ("deprecated", attribute_names
, attribute_values
);
388 MISSING_ATTRIBUTE (error
, element_name
, "name");
389 else if (typename
== NULL
)
390 MISSING_ATTRIBUTE (error
, element_name
, "type-name");
391 else if (typeinit
== NULL
)
392 MISSING_ATTRIBUTE (error
, element_name
, "get-type");
395 GIdlNodeBoxed
*boxed
;
397 boxed
= (GIdlNodeBoxed
*) g_idl_node_new (G_IDL_NODE_BOXED
);
399 ((GIdlNode
*)boxed
)->name
= g_strdup (name
);
400 boxed
->gtype_name
= g_strdup (typename
);
401 boxed
->gtype_init
= g_strdup (typeinit
);
402 if (deprecated
&& strcmp (deprecated
, "1") == 0)
403 boxed
->deprecated
= TRUE
;
405 boxed
->deprecated
= FALSE
;
407 ctx
->current_node
= (GIdlNode
*)boxed
;
408 ctx
->current_module
->entries
=
409 g_list_append (ctx
->current_module
->entries
, boxed
);
411 ctx
->state
= STATE_BOXED
;
421 start_function (GMarkupParseContext
*context
,
422 const gchar
*element_name
,
423 const gchar
**attribute_names
,
424 const gchar
**attribute_values
,
428 if ((ctx
->state
== STATE_NAMESPACE
&&
429 (strcmp (element_name
, "function") == 0 ||
430 strcmp (element_name
, "callback") == 0)) ||
431 ((ctx
->state
== STATE_OBJECT
||
432 ctx
->state
== STATE_INTERFACE
||
433 ctx
->state
== STATE_BOXED
||
434 ctx
->state
== STATE_STRUCT
||
435 ctx
->state
== STATE_UNION
) &&
436 strcmp (element_name
, "method") == 0) ||
437 ((ctx
->state
== STATE_OBJECT
||
438 ctx
->state
== STATE_BOXED
) &&
439 strcmp (element_name
, "constructor") == 0))
443 const gchar
*deprecated
;
446 name
= find_attribute ("name", attribute_names
, attribute_values
);
447 symbol
= find_attribute ("symbol", attribute_names
, attribute_values
);
448 deprecated
= find_attribute ("deprecated", attribute_names
, attribute_values
);
449 type
= find_attribute ("type", attribute_names
, attribute_values
);
452 MISSING_ATTRIBUTE (error
, element_name
, "name");
453 else if (strcmp (element_name
, "callback") != 0 && symbol
== NULL
)
454 MISSING_ATTRIBUTE (error
, element_name
, "symbol");
457 GIdlNodeFunction
*function
;
459 function
= (GIdlNodeFunction
*) g_idl_node_new (G_IDL_NODE_FUNCTION
);
461 ((GIdlNode
*)function
)->name
= g_strdup (name
);
462 function
->symbol
= g_strdup (symbol
);
463 function
->parameters
= NULL
;
464 if (deprecated
&& strcmp (deprecated
, "1") == 0)
465 function
->deprecated
= TRUE
;
467 function
->deprecated
= FALSE
;
469 if (strcmp (element_name
, "method") == 0 ||
470 strcmp (element_name
, "constructor") == 0)
472 function
->is_method
= TRUE
;
474 if (type
&& strcmp (type
, "setter") == 0)
475 function
->is_setter
= TRUE
;
476 else if (type
&& strcmp (type
, "getter") == 0)
477 function
->is_getter
= TRUE
;
479 if (strcmp (element_name
, "constructor") == 0)
480 function
->is_constructor
= TRUE
;
482 function
->is_constructor
= FALSE
;
486 function
->is_method
= FALSE
;
487 function
->is_setter
= FALSE
;
488 function
->is_getter
= FALSE
;
489 function
->is_constructor
= FALSE
;
490 if (strcmp (element_name
, "callback") == 0)
491 ((GIdlNode
*)function
)->type
= G_IDL_NODE_CALLBACK
;
494 if (ctx
->current_node
== NULL
)
496 ctx
->current_module
->entries
=
497 g_list_append (ctx
->current_module
->entries
, function
);
500 switch (ctx
->current_node
->type
)
502 case G_IDL_NODE_INTERFACE
:
503 case G_IDL_NODE_OBJECT
:
505 GIdlNodeInterface
*iface
;
507 iface
= (GIdlNodeInterface
*)ctx
->current_node
;
508 iface
->members
= g_list_append (iface
->members
, function
);
511 case G_IDL_NODE_BOXED
:
513 GIdlNodeBoxed
*boxed
;
515 boxed
= (GIdlNodeBoxed
*)ctx
->current_node
;
516 boxed
->members
= g_list_append (boxed
->members
, function
);
519 case G_IDL_NODE_STRUCT
:
521 GIdlNodeStruct
*struct_
;
523 struct_
= (GIdlNodeStruct
*)ctx
->current_node
;
524 struct_
->members
= g_list_append (struct_
->members
, function
); }
526 case G_IDL_NODE_UNION
:
528 GIdlNodeUnion
*union_
;
530 union_
= (GIdlNodeUnion
*)ctx
->current_node
;
531 union_
->members
= g_list_append (union_
->members
, function
);
535 g_assert_not_reached ();
538 ctx
->current_node
= (GIdlNode
*)function
;
539 ctx
->state
= STATE_FUNCTION
;
549 start_parameter (GMarkupParseContext
*context
,
550 const gchar
*element_name
,
551 const gchar
**attribute_names
,
552 const gchar
**attribute_values
,
556 if (strcmp (element_name
, "parameter") == 0 &&
557 ctx
->state
== STATE_PARAMETERS
)
561 const gchar
*direction
;
564 const gchar
*optional
;
566 const gchar
*transfer
;
568 type
= find_attribute ("type", attribute_names
, attribute_values
);
569 name
= find_attribute ("name", attribute_names
, attribute_values
);
570 direction
= find_attribute ("direction", attribute_names
, attribute_values
);
571 retval
= find_attribute ("retval", attribute_names
, attribute_values
);
572 dipper
= find_attribute ("dipper", attribute_names
, attribute_values
);
573 optional
= find_attribute ("optional", attribute_names
, attribute_values
);
574 nullok
= find_attribute ("null-ok", attribute_names
, attribute_values
);
575 transfer
= find_attribute ("transfer", attribute_names
, attribute_values
);
578 MISSING_ATTRIBUTE (error
, element_name
, "type");
579 else if (name
== NULL
)
580 MISSING_ATTRIBUTE (error
, element_name
, "name");
583 GIdlNodeParam
*param
;
585 param
= (GIdlNodeParam
*)g_idl_node_new (G_IDL_NODE_PARAM
);
587 if (direction
&& strcmp (direction
, "out") == 0)
592 else if (direction
&& strcmp (direction
, "inout") == 0)
603 if (retval
&& strcmp (retval
, "1") == 0)
604 param
->retval
= TRUE
;
606 param
->retval
= FALSE
;
608 if (dipper
&& strcmp (dipper
, "1") == 0)
609 param
->dipper
= TRUE
;
611 param
->dipper
= FALSE
;
613 if (optional
&& strcmp (optional
, "1") == 0)
614 param
->optional
= TRUE
;
616 param
->optional
= FALSE
;
618 if (nullok
&& strcmp (nullok
, "1") == 0)
619 param
->null_ok
= TRUE
;
621 param
->null_ok
= FALSE
;
623 if (transfer
&& strcmp (transfer
, "none") == 0)
625 param
->transfer
= FALSE
;
626 param
->shallow_transfer
= FALSE
;
628 else if (transfer
&& strcmp (transfer
, "shallow") == 0)
630 param
->transfer
= FALSE
;
631 param
->shallow_transfer
= TRUE
;
635 param
->transfer
= TRUE
;
636 param
->shallow_transfer
= FALSE
;
639 ((GIdlNode
*)param
)->name
= g_strdup (name
);
640 param
->type
= parse_type (type
);
642 switch (ctx
->current_node
->type
)
644 case G_IDL_NODE_FUNCTION
:
645 case G_IDL_NODE_CALLBACK
:
647 GIdlNodeFunction
*func
;
649 func
= (GIdlNodeFunction
*)ctx
->current_node
;
650 func
->parameters
= g_list_append (func
->parameters
, param
);
653 case G_IDL_NODE_SIGNAL
:
655 GIdlNodeSignal
*signal
;
657 signal
= (GIdlNodeSignal
*)ctx
->current_node
;
658 signal
->parameters
= g_list_append (signal
->parameters
, param
);
661 case G_IDL_NODE_VFUNC
:
663 GIdlNodeVFunc
*vfunc
;
665 vfunc
= (GIdlNodeVFunc
*)ctx
->current_node
;
666 vfunc
->parameters
= g_list_append (vfunc
->parameters
, param
);
670 g_assert_not_reached ();
681 start_field (GMarkupParseContext
*context
,
682 const gchar
*element_name
,
683 const gchar
**attribute_names
,
684 const gchar
**attribute_values
,
688 if (strcmp (element_name
, "field") == 0 &&
689 (ctx
->state
== STATE_OBJECT
||
690 ctx
->state
== STATE_BOXED
||
691 ctx
->state
== STATE_STRUCT
||
692 ctx
->state
== STATE_UNION
))
696 const gchar
*readable
;
697 const gchar
*writable
;
702 name
= find_attribute ("name", attribute_names
, attribute_values
);
703 type
= find_attribute ("type", attribute_names
, attribute_values
);
704 readable
= find_attribute ("readable", attribute_names
, attribute_values
);
705 writable
= find_attribute ("writable", attribute_names
, attribute_values
);
706 bits
= find_attribute ("bits", attribute_names
, attribute_values
);
707 branch
= find_attribute ("branch", attribute_names
, attribute_values
);
708 offset
= find_attribute ("offset", attribute_names
, attribute_values
);
711 MISSING_ATTRIBUTE (error
, element_name
, "name");
712 else if (type
== NULL
)
713 MISSING_ATTRIBUTE (error
, element_name
, "type");
716 GIdlNodeField
*field
;
718 field
= (GIdlNodeField
*)g_idl_node_new (G_IDL_NODE_FIELD
);
719 ((GIdlNode
*)field
)->name
= g_strdup (name
);
720 if (readable
&& strcmp (readable
, "1") == 0)
721 field
->readable
= TRUE
;
723 field
->readable
= FALSE
;
725 if (writable
&& strcmp (writable
, "1") == 0)
726 field
->writable
= TRUE
;
728 field
->writable
= FALSE
;
731 field
->bits
= atoi (bits
);
736 field
->offset
= atoi (offset
);
740 field
->type
= parse_type (type
);
742 switch (ctx
->current_node
->type
)
744 case G_IDL_NODE_OBJECT
:
746 GIdlNodeInterface
*iface
;
748 iface
= (GIdlNodeInterface
*)ctx
->current_node
;
749 iface
->members
= g_list_append (iface
->members
, field
);
752 case G_IDL_NODE_BOXED
:
754 GIdlNodeBoxed
*boxed
;
756 boxed
= (GIdlNodeBoxed
*)ctx
->current_node
;
757 boxed
->members
= g_list_append (boxed
->members
, field
);
760 case G_IDL_NODE_STRUCT
:
762 GIdlNodeStruct
*struct_
;
764 struct_
= (GIdlNodeStruct
*)ctx
->current_node
;
765 struct_
->members
= g_list_append (struct_
->members
, field
);
768 case G_IDL_NODE_UNION
:
770 GIdlNodeUnion
*union_
;
772 union_
= (GIdlNodeUnion
*)ctx
->current_node
;
773 union_
->members
= g_list_append (union_
->members
, field
);
776 GIdlNodeConstant
*constant
;
778 constant
= (GIdlNodeConstant
*) g_idl_node_new (G_IDL_NODE_CONSTANT
);
779 ((GIdlNode
*)constant
)->name
= g_strdup (name
);
780 constant
->value
= g_strdup (branch
);
781 constant
->type
= union_
->discriminator_type
;
782 constant
->deprecated
= FALSE
;
784 union_
->discriminators
= g_list_append (union_
->discriminators
, constant
);
789 g_assert_not_reached ();
799 start_enum (GMarkupParseContext
*context
,
800 const gchar
*element_name
,
801 const gchar
**attribute_names
,
802 const gchar
**attribute_values
,
806 if ((strcmp (element_name
, "enum") == 0 && ctx
->state
== STATE_NAMESPACE
) ||
807 (strcmp (element_name
, "flags") == 0 && ctx
->state
== STATE_NAMESPACE
))
810 const gchar
*typename
;
811 const gchar
*typeinit
;
812 const gchar
*deprecated
;
814 name
= find_attribute ("name", attribute_names
, attribute_values
);
815 typename
= find_attribute ("type-name", attribute_names
, attribute_values
);
816 typeinit
= find_attribute ("get-type", attribute_names
, attribute_values
);
817 deprecated
= find_attribute ("deprecated", attribute_names
, attribute_values
);
820 MISSING_ATTRIBUTE (error
, element_name
, "name");
825 if (strcmp (element_name
, "enum") == 0)
826 enum_
= (GIdlNodeEnum
*) g_idl_node_new (G_IDL_NODE_ENUM
);
828 enum_
= (GIdlNodeEnum
*) g_idl_node_new (G_IDL_NODE_FLAGS
);
829 ((GIdlNode
*)enum_
)->name
= g_strdup (name
);
830 enum_
->gtype_name
= g_strdup (typename
);
831 enum_
->gtype_init
= g_strdup (typeinit
);
832 if (deprecated
&& strcmp (deprecated
, "1") == 0)
833 enum_
->deprecated
= TRUE
;
835 enum_
->deprecated
= FALSE
;
837 ctx
->current_node
= (GIdlNode
*) enum_
;
838 ctx
->current_module
->entries
=
839 g_list_append (ctx
->current_module
->entries
, enum_
);
841 ctx
->state
= STATE_ENUM
;
850 start_property (GMarkupParseContext
*context
,
851 const gchar
*element_name
,
852 const gchar
**attribute_names
,
853 const gchar
**attribute_values
,
857 if (strcmp (element_name
, "property") == 0 &&
858 (ctx
->state
== STATE_OBJECT
||
859 ctx
->state
== STATE_INTERFACE
))
863 const gchar
*readable
;
864 const gchar
*writable
;
865 const gchar
*construct
;
866 const gchar
*construct_only
;
868 name
= find_attribute ("name", attribute_names
, attribute_values
);
869 type
= find_attribute ("type", attribute_names
, attribute_values
);
870 readable
= find_attribute ("readable", attribute_names
, attribute_values
);
871 writable
= find_attribute ("writable", attribute_names
, attribute_values
);
872 construct
= find_attribute ("construct", attribute_names
, attribute_values
);
873 construct_only
= find_attribute ("construct-only", attribute_names
, attribute_values
);
876 MISSING_ATTRIBUTE (error
, element_name
, "name");
877 else if (type
== NULL
)
878 MISSING_ATTRIBUTE (error
, element_name
, "type");
881 GIdlNodeProperty
*property
;
882 GIdlNodeInterface
*iface
;
884 property
= (GIdlNodeProperty
*) g_idl_node_new (G_IDL_NODE_PROPERTY
);
886 ((GIdlNode
*)property
)->name
= g_strdup (name
);
888 if (readable
&& strcmp (readable
, "1") == 0)
889 property
->readable
= TRUE
;
891 property
->readable
= FALSE
;
892 if (writable
&& strcmp (writable
, "1") == 0)
893 property
->writable
= TRUE
;
895 property
->writable
= FALSE
;
896 if (construct
&& strcmp (construct
, "1") == 0)
897 property
->construct
= TRUE
;
899 property
->construct
= FALSE
;
900 if (construct_only
&& strcmp (construct_only
, "1") == 0)
901 property
->construct_only
= TRUE
;
903 property
->construct_only
= FALSE
;
905 property
->type
= parse_type (type
);
907 iface
= (GIdlNodeInterface
*)ctx
->current_node
;
908 iface
->members
= g_list_append (iface
->members
, property
);
917 parse_value (const gchar
*str
)
921 /* FIXME just a quick hack */
922 shift_op
= strstr (str
, "<<");
928 base
= strtol (str
, NULL
, 10);
929 shift
= strtol (shift_op
+ 3, NULL
, 10);
931 return base
<< shift
;
934 return strtol (str
, NULL
, 10);
940 start_member (GMarkupParseContext
*context
,
941 const gchar
*element_name
,
942 const gchar
**attribute_names
,
943 const gchar
**attribute_values
,
947 if (strcmp (element_name
, "member") == 0 &&
948 ctx
->state
== STATE_ENUM
)
952 const gchar
*deprecated
;
954 name
= find_attribute ("name", attribute_names
, attribute_values
);
955 value
= find_attribute ("value", attribute_names
, attribute_values
);
956 deprecated
= find_attribute ("deprecated", attribute_names
, attribute_values
);
959 MISSING_ATTRIBUTE (error
, element_name
, "name");
963 GIdlNodeValue
*value_
;
965 value_
= (GIdlNodeValue
*) g_idl_node_new (G_IDL_NODE_VALUE
);
967 ((GIdlNode
*)value_
)->name
= g_strdup (name
);
969 value_
->value
= parse_value (value
);
971 if (deprecated
&& strcmp (deprecated
, "1") == 0)
972 value_
->deprecated
= TRUE
;
974 value_
->deprecated
= FALSE
;
976 enum_
= (GIdlNodeEnum
*)ctx
->current_node
;
977 enum_
->values
= g_list_append (enum_
->values
, value_
);
986 start_constant (GMarkupParseContext
*context
,
987 const gchar
*element_name
,
988 const gchar
**attribute_names
,
989 const gchar
**attribute_values
,
993 if (strcmp (element_name
, "constant") == 0 &&
994 (ctx
->state
== STATE_NAMESPACE
||
995 ctx
->state
== STATE_OBJECT
||
996 ctx
->state
== STATE_INTERFACE
))
1001 const gchar
*deprecated
;
1003 name
= find_attribute ("name", attribute_names
, attribute_values
);
1004 type
= find_attribute ("type", attribute_names
, attribute_values
);
1005 value
= find_attribute ("value", attribute_names
, attribute_values
);
1006 deprecated
= find_attribute ("deprecated", attribute_names
, attribute_values
);
1009 MISSING_ATTRIBUTE (error
, element_name
, "name");
1010 else if (type
== NULL
)
1011 MISSING_ATTRIBUTE (error
, element_name
, "type");
1012 else if (value
== NULL
)
1013 MISSING_ATTRIBUTE (error
, element_name
, "value");
1016 GIdlNodeConstant
*constant
;
1018 constant
= (GIdlNodeConstant
*) g_idl_node_new (G_IDL_NODE_CONSTANT
);
1020 ((GIdlNode
*)constant
)->name
= g_strdup (name
);
1021 constant
->value
= g_strdup (value
);
1023 constant
->type
= parse_type (type
);
1025 if (deprecated
&& strcmp (deprecated
, "1") == 0)
1026 constant
->deprecated
= TRUE
;
1028 constant
->deprecated
= FALSE
;
1030 if (ctx
->state
== STATE_NAMESPACE
)
1032 ctx
->current_node
= (GIdlNode
*) constant
;
1033 ctx
->current_module
->entries
=
1034 g_list_append (ctx
->current_module
->entries
, constant
);
1038 GIdlNodeInterface
*iface
;
1040 iface
= (GIdlNodeInterface
*)ctx
->current_node
;
1041 iface
->members
= g_list_append (iface
->members
, constant
);
1051 start_errordomain (GMarkupParseContext
*context
,
1052 const gchar
*element_name
,
1053 const gchar
**attribute_names
,
1054 const gchar
**attribute_values
,
1058 if (strcmp (element_name
, "errordomain") == 0 &&
1059 ctx
->state
== STATE_NAMESPACE
)
1062 const gchar
*getquark
;
1064 const gchar
*deprecated
;
1066 name
= find_attribute ("name", attribute_names
, attribute_values
);
1067 getquark
= find_attribute ("get-quark", attribute_names
, attribute_values
);
1068 codes
= find_attribute ("codes", attribute_names
, attribute_values
);
1069 deprecated
= find_attribute ("deprecated", attribute_names
, attribute_values
);
1072 MISSING_ATTRIBUTE (error
, element_name
, "name");
1073 else if (getquark
== NULL
)
1074 MISSING_ATTRIBUTE (error
, element_name
, "getquark");
1075 else if (codes
== NULL
)
1076 MISSING_ATTRIBUTE (error
, element_name
, "codes");
1079 GIdlNodeErrorDomain
*domain
;
1081 domain
= (GIdlNodeErrorDomain
*) g_idl_node_new (G_IDL_NODE_ERROR_DOMAIN
);
1083 ((GIdlNode
*)domain
)->name
= g_strdup (name
);
1084 domain
->getquark
= g_strdup (getquark
);
1085 domain
->codes
= g_strdup (codes
);
1087 if (deprecated
&& strcmp (deprecated
, "1") == 0)
1088 domain
->deprecated
= TRUE
;
1090 domain
->deprecated
= FALSE
;
1092 ctx
->current_node
= (GIdlNode
*) domain
;
1093 ctx
->current_module
->entries
=
1094 g_list_append (ctx
->current_module
->entries
, domain
);
1096 ctx
->state
= STATE_ERRORDOMAIN
;
1105 start_interface (GMarkupParseContext
*context
,
1106 const gchar
*element_name
,
1107 const gchar
**attribute_names
,
1108 const gchar
**attribute_values
,
1112 if (strcmp (element_name
, "interface") == 0 &&
1113 ctx
->state
== STATE_NAMESPACE
)
1116 const gchar
*typename
;
1117 const gchar
*typeinit
;
1118 const gchar
*deprecated
;
1120 name
= find_attribute ("name", attribute_names
, attribute_values
);
1121 typename
= find_attribute ("type-name", attribute_names
, attribute_values
);
1122 typeinit
= find_attribute ("get-type", attribute_names
, attribute_values
);
1123 deprecated
= find_attribute ("deprecated", attribute_names
, attribute_values
);
1126 MISSING_ATTRIBUTE (error
, element_name
, "name");
1127 else if (typename
== NULL
)
1128 MISSING_ATTRIBUTE (error
, element_name
, "type-name");
1129 else if (typeinit
== NULL
)
1130 MISSING_ATTRIBUTE (error
, element_name
, "get-type");
1133 GIdlNodeInterface
*iface
;
1135 iface
= (GIdlNodeInterface
*) g_idl_node_new (G_IDL_NODE_INTERFACE
);
1136 ((GIdlNode
*)iface
)->name
= g_strdup (name
);
1137 iface
->gtype_name
= g_strdup (typename
);
1138 iface
->gtype_init
= g_strdup (typeinit
);
1139 if (deprecated
&& strcmp (deprecated
, "1") == 0)
1140 iface
->deprecated
= TRUE
;
1142 iface
->deprecated
= FALSE
;
1144 ctx
->current_node
= (GIdlNode
*) iface
;
1145 ctx
->current_module
->entries
=
1146 g_list_append (ctx
->current_module
->entries
, iface
);
1148 ctx
->state
= STATE_INTERFACE
;
1158 start_object (GMarkupParseContext
*context
,
1159 const gchar
*element_name
,
1160 const gchar
**attribute_names
,
1161 const gchar
**attribute_values
,
1165 if (strcmp (element_name
, "object") == 0 &&
1166 ctx
->state
== STATE_NAMESPACE
)
1169 const gchar
*parent
;
1170 const gchar
*typename
;
1171 const gchar
*typeinit
;
1172 const gchar
*deprecated
;
1174 name
= find_attribute ("name", attribute_names
, attribute_values
);
1175 parent
= find_attribute ("parent", attribute_names
, attribute_values
);
1176 typename
= find_attribute ("type-name", attribute_names
, attribute_values
);
1177 typeinit
= find_attribute ("get-type", attribute_names
, attribute_values
);
1178 deprecated
= find_attribute ("deprecated", attribute_names
, attribute_values
);
1181 MISSING_ATTRIBUTE (error
, element_name
, "name");
1182 else if (typename
== NULL
)
1183 MISSING_ATTRIBUTE (error
, element_name
, "type-name");
1184 else if (typeinit
== NULL
)
1185 MISSING_ATTRIBUTE (error
, element_name
, "get-type");
1188 GIdlNodeInterface
*iface
;
1190 iface
= (GIdlNodeInterface
*) g_idl_node_new (G_IDL_NODE_OBJECT
);
1191 ((GIdlNode
*)iface
)->name
= g_strdup (name
);
1192 iface
->gtype_name
= g_strdup (typename
);
1193 iface
->gtype_init
= g_strdup (typeinit
);
1194 iface
->parent
= g_strdup (parent
);
1195 if (deprecated
&& strcmp (deprecated
, "1") == 0)
1196 iface
->deprecated
= TRUE
;
1198 iface
->deprecated
= FALSE
;
1200 ctx
->current_node
= (GIdlNode
*) iface
;
1201 ctx
->current_module
->entries
=
1202 g_list_append (ctx
->current_module
->entries
, iface
);
1204 ctx
->state
= STATE_OBJECT
;
1213 start_return_type (GMarkupParseContext
*context
,
1214 const gchar
*element_name
,
1215 const gchar
**attribute_names
,
1216 const gchar
**attribute_values
,
1220 if (strcmp (element_name
, "return-type") == 0 &&
1221 ctx
->state
== STATE_FUNCTION
)
1224 const gchar
*nullok
;
1225 const gchar
*transfer
;
1227 type
= find_attribute ("type", attribute_names
, attribute_values
);
1228 nullok
= find_attribute ("null-ok", attribute_names
, attribute_values
);
1229 transfer
= find_attribute ("transfer", attribute_names
, attribute_values
);
1231 MISSING_ATTRIBUTE (error
, element_name
, "type");
1234 GIdlNodeParam
*param
;
1236 param
= (GIdlNodeParam
*)g_idl_node_new (G_IDL_NODE_PARAM
);
1239 param
->retval
= TRUE
;
1240 if (nullok
&& strcmp (nullok
, "1") == 0)
1241 param
->null_ok
= TRUE
;
1243 param
->null_ok
= FALSE
;
1244 if (transfer
&& strcmp (transfer
, "none") == 0)
1246 param
->transfer
= FALSE
;
1247 param
->shallow_transfer
= FALSE
;
1249 else if (transfer
&& strcmp (transfer
, "shallow") == 0)
1251 param
->transfer
= FALSE
;
1252 param
->shallow_transfer
= TRUE
;
1256 param
->transfer
= TRUE
;
1257 param
->shallow_transfer
= FALSE
;
1260 param
->type
= parse_type (type
);
1262 switch (ctx
->current_node
->type
)
1264 case G_IDL_NODE_FUNCTION
:
1265 case G_IDL_NODE_CALLBACK
:
1267 GIdlNodeFunction
*func
= (GIdlNodeFunction
*)ctx
->current_node
;
1268 func
->result
= param
;
1271 case G_IDL_NODE_SIGNAL
:
1273 GIdlNodeSignal
*signal
= (GIdlNodeSignal
*)ctx
->current_node
;
1274 signal
->result
= param
;
1277 case G_IDL_NODE_VFUNC
:
1279 GIdlNodeVFunc
*vfunc
= (GIdlNodeVFunc
*)ctx
->current_node
;
1280 vfunc
->result
= param
;
1284 g_assert_not_reached ();
1295 start_signal (GMarkupParseContext
*context
,
1296 const gchar
*element_name
,
1297 const gchar
**attribute_names
,
1298 const gchar
**attribute_values
,
1302 if (strcmp (element_name
, "signal") == 0 &&
1303 (ctx
->state
== STATE_OBJECT
||
1304 ctx
->state
== STATE_INTERFACE
))
1308 const gchar
*no_recurse
;
1309 const gchar
*detailed
;
1310 const gchar
*action
;
1311 const gchar
*no_hooks
;
1312 const gchar
*has_class_closure
;
1314 name
= find_attribute ("name", attribute_names
, attribute_values
);
1315 when
= find_attribute ("when", attribute_names
, attribute_values
);
1316 no_recurse
= find_attribute ("no-recurse", attribute_names
, attribute_values
);
1317 detailed
= find_attribute ("detailed", attribute_names
, attribute_values
);
1318 action
= find_attribute ("action", attribute_names
, attribute_values
);
1319 no_hooks
= find_attribute ("no-hooks", attribute_names
, attribute_values
);
1320 has_class_closure
= find_attribute ("has-class-closure", attribute_names
, attribute_values
);
1323 MISSING_ATTRIBUTE (error
, element_name
, "name");
1324 else if (when
== NULL
)
1325 MISSING_ATTRIBUTE (error
, element_name
, "when");
1328 GIdlNodeInterface
*iface
;
1329 GIdlNodeSignal
*signal
;
1331 signal
= (GIdlNodeSignal
*)g_idl_node_new (G_IDL_NODE_SIGNAL
);
1333 ((GIdlNode
*)signal
)->name
= g_strdup (name
);
1335 signal
->run_first
= FALSE
;
1336 signal
->run_last
= FALSE
;
1337 signal
->run_cleanup
= FALSE
;
1338 if (strcmp (when
, "FIRST") == 0)
1339 signal
->run_first
= TRUE
;
1340 else if (strcmp (when
, "LAST") == 0)
1341 signal
->run_last
= TRUE
;
1343 signal
->run_cleanup
= TRUE
;
1345 if (no_recurse
&& strcmp (no_recurse
, "1") == 0)
1346 signal
->no_recurse
= TRUE
;
1348 signal
->no_recurse
= FALSE
;
1349 if (detailed
&& strcmp (detailed
, "1") == 0)
1350 signal
->detailed
= TRUE
;
1352 signal
->detailed
= FALSE
;
1353 if (action
&& strcmp (action
, "1") == 0)
1354 signal
->action
= TRUE
;
1356 signal
->action
= FALSE
;
1357 if (no_hooks
&& strcmp (no_hooks
, "1") == 0)
1358 signal
->no_hooks
= TRUE
;
1360 signal
->no_hooks
= FALSE
;
1361 if (has_class_closure
&& strcmp (has_class_closure
, "1") == 0)
1362 signal
->has_class_closure
= TRUE
;
1364 signal
->has_class_closure
= FALSE
;
1366 iface
= (GIdlNodeInterface
*)ctx
->current_node
;
1367 iface
->members
= g_list_append (iface
->members
, signal
);
1369 ctx
->current_node
= (GIdlNode
*)signal
;
1370 ctx
->state
= STATE_FUNCTION
;
1379 start_vfunc (GMarkupParseContext
*context
,
1380 const gchar
*element_name
,
1381 const gchar
**attribute_names
,
1382 const gchar
**attribute_values
,
1386 if (strcmp (element_name
, "vfunc") == 0 &&
1387 (ctx
->state
== STATE_OBJECT
||
1388 ctx
->state
== STATE_INTERFACE
))
1391 const gchar
*must_chain_up
;
1392 const gchar
*override
;
1393 const gchar
*is_class_closure
;
1394 const gchar
*offset
;
1396 name
= find_attribute ("name", attribute_names
, attribute_values
);
1397 must_chain_up
= find_attribute ("must-chain-up", attribute_names
, attribute_values
);
1398 override
= find_attribute ("override", attribute_names
, attribute_values
);
1399 is_class_closure
= find_attribute ("is-class-closure", attribute_names
, attribute_values
);
1400 offset
= find_attribute ("offset", attribute_names
, attribute_values
);
1403 MISSING_ATTRIBUTE (error
, element_name
, "name");
1406 GIdlNodeInterface
*iface
;
1407 GIdlNodeVFunc
*vfunc
;
1409 vfunc
= (GIdlNodeVFunc
*)g_idl_node_new (G_IDL_NODE_VFUNC
);
1411 ((GIdlNode
*)vfunc
)->name
= g_strdup (name
);
1413 if (must_chain_up
&& strcmp (must_chain_up
, "1") == 0)
1414 vfunc
->must_chain_up
= TRUE
;
1416 vfunc
->must_chain_up
= FALSE
;
1418 if (override
&& strcmp (override
, "always") == 0)
1420 vfunc
->must_be_implemented
= TRUE
;
1421 vfunc
->must_not_be_implemented
= FALSE
;
1423 else if (override
&& strcmp (override
, "never") == 0)
1425 vfunc
->must_be_implemented
= FALSE
;
1426 vfunc
->must_not_be_implemented
= TRUE
;
1430 vfunc
->must_be_implemented
= FALSE
;
1431 vfunc
->must_not_be_implemented
= FALSE
;
1434 if (is_class_closure
&& strcmp (is_class_closure
, "1") == 0)
1435 vfunc
->is_class_closure
= TRUE
;
1437 vfunc
->is_class_closure
= FALSE
;
1440 vfunc
->offset
= atoi (offset
);
1444 iface
= (GIdlNodeInterface
*)ctx
->current_node
;
1445 iface
->members
= g_list_append (iface
->members
, vfunc
);
1447 ctx
->current_node
= (GIdlNode
*)vfunc
;
1448 ctx
->state
= STATE_FUNCTION
;
1458 start_struct (GMarkupParseContext
*context
,
1459 const gchar
*element_name
,
1460 const gchar
**attribute_names
,
1461 const gchar
**attribute_values
,
1465 if (strcmp (element_name
, "struct") == 0 &&
1466 ctx
->state
== STATE_NAMESPACE
)
1469 const gchar
*deprecated
;
1471 name
= find_attribute ("name", attribute_names
, attribute_values
);
1472 deprecated
= find_attribute ("deprecated", attribute_names
, attribute_values
);
1475 MISSING_ATTRIBUTE (error
, element_name
, "name");
1478 GIdlNodeStruct
*struct_
;
1480 struct_
= (GIdlNodeStruct
*) g_idl_node_new (G_IDL_NODE_STRUCT
);
1482 ((GIdlNode
*)struct_
)->name
= g_strdup (name
);
1483 if (deprecated
&& strcmp (deprecated
, "1") == 0)
1484 struct_
->deprecated
= TRUE
;
1486 struct_
->deprecated
= FALSE
;
1488 ctx
->current_node
= (GIdlNode
*)struct_
;
1489 ctx
->current_module
->entries
=
1490 g_list_append (ctx
->current_module
->entries
, struct_
);
1492 ctx
->state
= STATE_STRUCT
;
1501 start_union (GMarkupParseContext
*context
,
1502 const gchar
*element_name
,
1503 const gchar
**attribute_names
,
1504 const gchar
**attribute_values
,
1508 if (strcmp (element_name
, "union") == 0 &&
1509 ctx
->state
== STATE_NAMESPACE
)
1512 const gchar
*deprecated
;
1513 const gchar
*typename
;
1514 const gchar
*typeinit
;
1516 name
= find_attribute ("name", attribute_names
, attribute_values
);
1517 deprecated
= find_attribute ("deprecated", attribute_names
, attribute_values
);
1518 typename
= find_attribute ("type-name", attribute_names
, attribute_values
);
1519 typeinit
= find_attribute ("get-type", attribute_names
, attribute_values
);
1522 MISSING_ATTRIBUTE (error
, element_name
, "name");
1525 GIdlNodeUnion
*union_
;
1527 union_
= (GIdlNodeUnion
*) g_idl_node_new (G_IDL_NODE_UNION
);
1529 ((GIdlNode
*)union_
)->name
= g_strdup (name
);
1530 union_
->gtype_name
= g_strdup (typename
);
1531 union_
->gtype_init
= g_strdup (typeinit
);
1532 if (deprecated
&& strcmp (deprecated
, "1") == 0)
1533 union_
->deprecated
= TRUE
;
1535 union_
->deprecated
= FALSE
;
1537 ctx
->current_node
= (GIdlNode
*)union_
;
1538 ctx
->current_module
->entries
=
1539 g_list_append (ctx
->current_module
->entries
, union_
);
1541 ctx
->state
= STATE_UNION
;
1549 start_discriminator (GMarkupParseContext
*context
,
1550 const gchar
*element_name
,
1551 const gchar
**attribute_names
,
1552 const gchar
**attribute_values
,
1556 if (strcmp (element_name
, "discriminator") == 0 &&
1557 ctx
->state
== STATE_UNION
)
1560 const gchar
*offset
;
1562 type
= find_attribute ("type", attribute_names
, attribute_values
);
1563 offset
= find_attribute ("offset", attribute_names
, attribute_values
);
1565 MISSING_ATTRIBUTE (error
, element_name
, "type");
1566 else if (offset
== NULL
)
1567 MISSING_ATTRIBUTE (error
, element_name
, "offset");
1569 ((GIdlNodeUnion
*)ctx
->current_node
)->discriminator_type
1570 = parse_type (type
);
1571 ((GIdlNodeUnion
*)ctx
->current_node
)->discriminator_offset
1582 start_element_handler (GMarkupParseContext
*context
,
1583 const gchar
*element_name
,
1584 const gchar
**attribute_names
,
1585 const gchar
**attribute_values
,
1589 ParseContext
*ctx
= user_data
;
1590 gint line_number
, char_number
;
1592 switch (element_name
[0])
1595 if (strcmp (element_name
, "api") == 0 && ctx
->state
== STATE_START
)
1597 const gchar
*version
;
1599 version
= find_attribute ("version", attribute_names
, attribute_values
);
1601 if (version
== NULL
)
1602 MISSING_ATTRIBUTE (error
, element_name
, "version");
1603 else if (strcmp (version
, "1.0") != 0)
1606 G_MARKUP_ERROR_INVALID_CONTENT
,
1607 "Unsupported version '%s'",
1610 ctx
->state
= STATE_ROOT
;
1617 if (start_boxed (context
, element_name
,
1618 attribute_names
, attribute_values
,
1624 if (start_function (context
, element_name
,
1625 attribute_names
, attribute_values
,
1628 else if (start_constant (context
, element_name
,
1629 attribute_names
, attribute_values
,
1635 if (start_discriminator (context
, element_name
,
1636 attribute_names
, attribute_values
,
1642 if (start_enum (context
, element_name
,
1643 attribute_names
, attribute_values
,
1646 else if (start_errordomain (context
, element_name
,
1647 attribute_names
, attribute_values
,
1653 if (start_function (context
, element_name
,
1654 attribute_names
, attribute_values
,
1657 else if (start_field (context
, element_name
,
1658 attribute_names
, attribute_values
,
1661 else if (start_enum (context
, element_name
,
1662 attribute_names
, attribute_values
,
1669 if (start_interface (context
, element_name
,
1670 attribute_names
, attribute_values
,
1673 if (strcmp (element_name
, "implements") == 0 &&
1674 ctx
->state
== STATE_OBJECT
)
1676 ctx
->state
= STATE_IMPLEMENTS
;
1680 else if (strcmp (element_name
, "interface") == 0 &&
1681 ctx
->state
== STATE_IMPLEMENTS
)
1685 name
= find_attribute ("name", attribute_names
, attribute_values
);
1688 MISSING_ATTRIBUTE (error
, element_name
, "name");
1691 GIdlNodeInterface
*iface
;
1693 iface
= (GIdlNodeInterface
*)ctx
->current_node
;
1694 iface
->interfaces
= g_list_append (iface
->interfaces
, g_strdup (name
));
1699 else if (strcmp (element_name
, "interface") == 0 &&
1700 ctx
->state
== STATE_REQUIRES
)
1704 name
= find_attribute ("name", attribute_names
, attribute_values
);
1707 MISSING_ATTRIBUTE (error
, element_name
, "name");
1710 GIdlNodeInterface
*iface
;
1712 iface
= (GIdlNodeInterface
*)ctx
->current_node
;
1713 iface
->prerequisites
= g_list_append (iface
->prerequisites
, g_strdup (name
));
1721 if (start_function (context
, element_name
,
1722 attribute_names
, attribute_values
,
1725 else if (start_member (context
, element_name
,
1726 attribute_names
, attribute_values
,
1732 if (strcmp (element_name
, "namespace") == 0 && ctx
->state
== STATE_ROOT
)
1734 const gchar
*name
, *shared_library
;
1736 name
= find_attribute ("name", attribute_names
, attribute_values
);
1737 shared_library
= find_attribute ("shared-library", attribute_names
, attribute_values
);
1740 MISSING_ATTRIBUTE (error
, element_name
, "name");
1743 ctx
->current_module
= g_idl_module_new (name
, shared_library
);
1744 ctx
->modules
= g_list_append (ctx
->modules
, ctx
->current_module
);
1746 ctx
->state
= STATE_NAMESPACE
;
1754 if (start_object (context
, element_name
,
1755 attribute_names
, attribute_values
,
1758 else if (strcmp (element_name
, "object") == 0 &&
1759 ctx
->state
== STATE_REQUIRES
)
1763 name
= find_attribute ("name", attribute_names
, attribute_values
);
1766 MISSING_ATTRIBUTE (error
, element_name
, "name");
1769 GIdlNodeInterface
*iface
;
1771 iface
= (GIdlNodeInterface
*)ctx
->current_node
;
1772 iface
->prerequisites
= g_list_append (iface
->prerequisites
, g_strdup (name
));
1780 if (start_property (context
, element_name
,
1781 attribute_names
, attribute_values
,
1784 else if (strcmp (element_name
, "parameters") == 0 &&
1785 ctx
->state
== STATE_FUNCTION
)
1787 ctx
->state
= STATE_PARAMETERS
;
1791 else if (start_parameter (context
, element_name
,
1792 attribute_names
, attribute_values
,
1799 if (start_return_type (context
, element_name
,
1800 attribute_names
, attribute_values
,
1803 else if (strcmp (element_name
, "requires") == 0 &&
1804 ctx
->state
== STATE_INTERFACE
)
1806 ctx
->state
= STATE_REQUIRES
;
1814 if (start_signal (context
, element_name
,
1815 attribute_names
, attribute_values
,
1818 else if (start_struct (context
, element_name
,
1819 attribute_names
, attribute_values
,
1826 if (start_union (context
, element_name
,
1827 attribute_names
, attribute_values
,
1833 if (start_vfunc (context
, element_name
,
1834 attribute_names
, attribute_values
,
1840 g_markup_parse_context_get_position (context
, &line_number
, &char_number
);
1844 G_MARKUP_ERROR_UNKNOWN_ELEMENT
,
1845 "Unexpected start tag '%s' on line %d char %d",
1847 line_number
, char_number
);
1854 end_element_handler (GMarkupParseContext
*context
,
1855 const gchar
*element_name
,
1859 ParseContext
*ctx
= user_data
;
1865 /* no need to GError here, GMarkup already catches this */
1869 ctx
->state
= STATE_END
;
1872 case STATE_NAMESPACE
:
1873 if (strcmp (element_name
, "namespace") == 0)
1875 ctx
->current_module
= NULL
;
1876 ctx
->state
= STATE_ROOT
;
1880 case STATE_FUNCTION
:
1881 if (strcmp (element_name
, "return-type") == 0)
1884 else if (ctx
->current_node
== g_list_last (ctx
->current_module
->entries
)->data
)
1886 ctx
->current_node
= NULL
;
1887 ctx
->state
= STATE_NAMESPACE
;
1891 ctx
->current_node
= g_list_last (ctx
->current_module
->entries
)->data
;
1892 if (ctx
->current_node
->type
== G_IDL_NODE_INTERFACE
)
1893 ctx
->state
= STATE_INTERFACE
;
1894 else if (ctx
->current_node
->type
== G_IDL_NODE_OBJECT
)
1895 ctx
->state
= STATE_OBJECT
;
1896 else if (ctx
->current_node
->type
== G_IDL_NODE_BOXED
)
1897 ctx
->state
= STATE_BOXED
;
1898 else if (ctx
->current_node
->type
== G_IDL_NODE_STRUCT
)
1899 ctx
->state
= STATE_STRUCT
;
1900 else if (ctx
->current_node
->type
== G_IDL_NODE_UNION
)
1901 ctx
->state
= STATE_UNION
;
1906 if (strcmp (element_name
, "object") == 0)
1908 ctx
->current_node
= NULL
;
1909 ctx
->state
= STATE_NAMESPACE
;
1913 case STATE_ERRORDOMAIN
:
1914 if (strcmp (element_name
, "errordomain") == 0)
1916 ctx
->current_node
= NULL
;
1917 ctx
->state
= STATE_NAMESPACE
;
1921 case STATE_INTERFACE
:
1922 if (strcmp (element_name
, "interface") == 0)
1924 ctx
->current_node
= NULL
;
1925 ctx
->state
= STATE_NAMESPACE
;
1930 if (strcmp (element_name
, "enum") == 0 ||
1931 strcmp (element_name
, "flags") == 0)
1933 ctx
->current_node
= NULL
;
1934 ctx
->state
= STATE_NAMESPACE
;
1939 if (strcmp (element_name
, "boxed") == 0)
1941 ctx
->current_node
= NULL
;
1942 ctx
->state
= STATE_NAMESPACE
;
1947 if (strcmp (element_name
, "struct") == 0)
1949 ctx
->current_node
= NULL
;
1950 ctx
->state
= STATE_NAMESPACE
;
1954 if (strcmp (element_name
, "union") == 0)
1956 ctx
->current_node
= NULL
;
1957 ctx
->state
= STATE_NAMESPACE
;
1961 case STATE_IMPLEMENTS
:
1962 if (strcmp (element_name
, "implements") == 0)
1963 ctx
->state
= STATE_OBJECT
;
1965 case STATE_REQUIRES
:
1966 if (strcmp (element_name
, "requires") == 0)
1967 ctx
->state
= STATE_INTERFACE
;
1969 case STATE_PARAMETERS
:
1970 if (strcmp (element_name
, "parameters") == 0)
1971 ctx
->state
= STATE_FUNCTION
;
1974 g_error ("Unhandled state %d in end_element_handler\n", ctx
->state
);
1979 text_handler (GMarkupParseContext
*context
,
1985 /* FIXME warn about non-whitespace text */
1989 cleanup (GMarkupParseContext
*context
,
1993 ParseContext
*ctx
= user_data
;
1996 for (m
= ctx
->modules
; m
; m
= m
->next
)
1997 g_idl_module_free (m
->data
);
1998 g_list_free (ctx
->modules
);
1999 ctx
->modules
= NULL
;
2001 ctx
->current_module
= NULL
;
2004 static GMarkupParser parser
=
2006 start_element_handler
,
2007 end_element_handler
,
2014 g_idl_parse_string (const gchar
*buffer
,
2018 ParseContext ctx
= { 0 };
2019 GMarkupParseContext
*context
;
2021 ctx
.state
= STATE_START
;
2023 context
= g_markup_parse_context_new (&parser
, 0, &ctx
, NULL
);
2024 if (!g_markup_parse_context_parse (context
, buffer
, length
, error
))
2027 if (!g_markup_parse_context_end_parse (context
, error
))
2032 g_markup_parse_context_free (context
);
2038 g_idl_parse_file (const gchar
*filename
,
2045 if (!g_file_get_contents (filename
, &buffer
, &length
, error
))
2048 modules
= g_idl_parse_string (buffer
, length
, error
);