summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@src.gnome.org>2008-09-06 20:33:51 +0000
committerColin Walters <walters@src.gnome.org>2008-09-06 20:33:51 +0000
commite28078c70cbf4a57c7dbd39626f43f9bd2674145 (patch)
tree1ab870b5a41cbc3e3a8a70f62b83f6e419049737
parentc5eb6a47cedf58210b4d3d73baced9a253e8ae51 (diff)
downloadgobject-introspection-e28078c70cbf4a57c7dbd39626f43f9bd2674145.tar.gz
Allow both union and struct to be boxed or not
* girepository/girnode.c: Allow gtype_name and gtype_init in struct and union. * girepository/girparser.c: Parse glib: boxed bits for both structure and union. * girepository/gtypelib.c: Don't barf if structure is boxed. * giscanner/girparser.py: Parse new XML format. * giscanner/girwriter.py: Write out new XML format. * giscanner/glibast.py: Define new classes which are both Boxed and Struct/Union, as well as an "Other" for everything else. * giscanner/glibtransformer.py: Handle boxed types specially; we try to merge them with a struct/union if one exists, otherwise fall back to generic boxed. * tests/*: Update. * tools/generate.c: Write out new format. svn path=/trunk/; revision=575
-rw-r--r--girepository/girnode.c26
-rw-r--r--girepository/girnode.h3
-rw-r--r--girepository/girparser.c51
-rw-r--r--girepository/gtypelib.c12
-rw-r--r--giscanner/girparser.py36
-rw-r--r--giscanner/girwriter.py45
-rw-r--r--giscanner/glibast.py30
-rw-r--r--giscanner/glibtransformer.py62
-rw-r--r--tests/scanner/foo-expected.gir23
-rw-r--r--tests/scanner/utility-expected.gir3
-rw-r--r--tools/generate.c11
11 files changed, 205 insertions, 97 deletions
diff --git a/girepository/girnode.c b/girepository/girnode.c
index fd74dd9f..2c557b5c 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -339,6 +339,9 @@ g_ir_node_free (GIrNode *node)
GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
g_free (node->name);
+ g_free (struct_->gtype_name);
+ g_free (struct_->gtype_init);
+
for (l = struct_->members; l; l = l->next)
g_ir_node_free ((GIrNode *)l->data);
g_list_free (struct_->members);
@@ -706,6 +709,10 @@ g_ir_node_get_full_size_internal (GIrNode *parent,
size = 20;
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ if (struct_->gtype_name)
+ size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4);
+ if (struct_->gtype_init)
+ size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4);
for (l = struct_->members; l; l = l->next)
size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
}
@@ -809,6 +816,10 @@ g_ir_node_get_full_size_internal (GIrNode *parent,
size = 28;
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ if (union_->gtype_name)
+ size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4);
+ if (union_->gtype_init)
+ size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4);
for (l = union_->members; l; l = l->next)
size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
for (l = union_->discriminators; l; l = l->next)
@@ -1594,11 +1605,20 @@ g_ir_node_build_typelib (GIrNode *node,
blob->blob_type = BLOB_TYPE_STRUCT;
blob->deprecated = struct_->deprecated;
- blob->unregistered = TRUE;
blob->reserved = 0;
blob->name = write_string (node->name, strings, data, offset2);
- blob->gtype_name = 0;
- blob->gtype_init = 0;
+ if (struct_->gtype_name)
+ {
+ blob->unregistered = FALSE;
+ blob->gtype_name = write_string (struct_->gtype_name, strings, data, offset2);
+ blob->gtype_init = write_string (struct_->gtype_init, strings, data, offset2);
+ }
+ else
+ {
+ blob->unregistered = TRUE;
+ blob->gtype_name = 0;
+ blob->gtype_init = 0;
+ }
blob->n_fields = 0;
blob->n_methods = 0;
diff --git a/girepository/girnode.h b/girepository/girnode.h
index 6079d367..67027aec 100644
--- a/girepository/girnode.h
+++ b/girepository/girnode.h
@@ -272,6 +272,9 @@ struct _GIrNodeStruct
GIrNode node;
gboolean deprecated;
+
+ gchar *gtype_name;
+ gchar *gtype_init;
GList *members;
};
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 11152d84..980d58d4 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -1889,30 +1889,47 @@ start_struct (GMarkupParseContext *context,
{
const gchar *name;
const gchar *deprecated;
+ const gchar *gtype_name;
+ const gchar *gtype_init;
+ GIrNodeStruct *struct_;
name = find_attribute ("name", attribute_names, attribute_values);
deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
-
+ gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
+ gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
+
if (name == NULL)
- MISSING_ATTRIBUTE (context, error, element_name, "name");
- else
{
- GIrNodeStruct *struct_;
+ MISSING_ATTRIBUTE (context, error, element_name, "name");
+ return FALSE;
+ }
+ if ((gtype_name == NULL && gtype_init != NULL))
+ {
+ MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name");
+ return FALSE;
+ }
+ if ((gtype_name != NULL && gtype_init == NULL))
+ {
+ MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
+ return FALSE;
+ }
- struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
-
- ((GIrNode *)struct_)->name = g_strdup (name);
- if (deprecated && strcmp (deprecated, "1") == 0)
- struct_->deprecated = TRUE;
- else
- struct_->deprecated = FALSE;
+ struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
+
+ ((GIrNode *)struct_)->name = g_strdup (name);
+ if (deprecated && strcmp (deprecated, "1") == 0)
+ struct_->deprecated = TRUE;
+ else
+ struct_->deprecated = FALSE;
- ctx->current_node = (GIrNode *)struct_;
- ctx->current_module->entries =
- g_list_append (ctx->current_module->entries, struct_);
-
- state_switch (ctx, STATE_STRUCT);
- }
+ struct_->gtype_name = g_strdup (gtype_name);
+ struct_->gtype_init = g_strdup (gtype_init);
+
+ ctx->current_node = (GIrNode *)struct_;
+ ctx->current_module->entries =
+ g_list_append (ctx->current_module->entries, struct_);
+
+ state_switch (ctx, STATE_STRUCT);
return TRUE;
}
return FALSE;
diff --git a/girepository/gtypelib.c b/girepository/gtypelib.c
index 3940a329..50abcb57 100644
--- a/girepository/gtypelib.c
+++ b/girepository/gtypelib.c
@@ -1173,23 +1173,13 @@ validate_struct_blob (ValidateContext *ctx,
"Wrong blob type");
return FALSE;
}
-
- if ((blob->blob_type == BLOB_TYPE_BOXED && blob->unregistered) ||
- (blob->blob_type == BLOB_TYPE_STRUCT && !blob->unregistered))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Registration/blob type mismatch");
- return FALSE;
- }
if (!validate_name (typelib, "struct", typelib->data, blob->name, error))
return FALSE;
push_context (ctx, get_string_nofail (typelib, blob->name));
- if (blob_type == BLOB_TYPE_BOXED)
+ if (!blob->unregistered)
{
if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_name, error))
return FALSE;
diff --git a/giscanner/girparser.py b/giscanner/girparser.py
index 5c2f121a..e344fb42 100644
--- a/giscanner/girparser.py
+++ b/giscanner/girparser.py
@@ -20,9 +20,11 @@
from xml.etree.cElementTree import parse
-from .ast import Alias, Callback, Function, Parameter, Return, Struct, Type
-from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
- GLibInterface, GLibObject)
+from .ast import (Alias, Callback, Function, Parameter, Return, Union,
+ Struct, Type)
+from .glibast import (GLibEnum, GLibEnumMember, GLibFlags,
+ GLibInterface, GLibObject, GLibBoxedStruct,
+ GLibBoxedUnion, GLibBoxedOther)
CORE_NS = "http://www.gtk.org/introspection/core/1.0"
C_NS = "http://www.gtk.org/introspection/c/1.0"
@@ -90,6 +92,8 @@ class GIRParser(object):
self._parse_object_interface(node)
elif node.tag == _corens('record'):
self._parse_struct(node)
+ elif node.tag == _corens('union'):
+ self._parse_union(node)
elif node.tag == _glibns('boxed'):
self._parse_boxed(node)
elif node.tag in [_corens('enumeration'),
@@ -137,8 +141,23 @@ class GIRParser(object):
return klass(name, retval, parameters, identifier)
def _parse_struct(self, node):
- struct = Struct(node.attrib['name'],
- node.attrib[_cns('type')])
+ if _glibns('type-name') in node.attrib:
+ struct = GLibBoxedStruct(node.attrib['name'],
+ node.attrib[_glibns('type-name')],
+ node.attrib[_glibns('get-type')])
+ else:
+ struct = Struct(node.attrib['name'],
+ node.attrib[_cns('type')])
+ self._add_node(struct)
+
+ def _parse_union(self, node):
+ if _glibns('type-name') in node.attrib:
+ struct = GLibBoxedUnion(node.attrib['name'],
+ node.attrib[_glibns('type-name')],
+ node.attrib[_glibns('get-type')])
+ else:
+ struct = Union(node.attrib['name'],
+ node.attrib[_cns('type')])
self._add_node(struct)
def _parse_type(self, node):
@@ -149,10 +168,9 @@ class GIRParser(object):
typenode.attrib[_cns('type')])
def _parse_boxed(self, node):
- obj = GLibBoxed(node.attrib[_glibns('name')],
- node.attrib[_glibns('type-name')],
- node.attrib[_glibns('get-type')],
- node.attrib.get(_cns('type')))
+ obj = GLibBoxedOther(node.attrib[_glibns('name')],
+ node.attrib[_glibns('type-name')],
+ node.attrib[_glibns('get-type')])
for method in node.findall(_corens('method')):
obj.methods.append(self._parse_function(method, Function))
for ctor in node.findall(_corens('constructor')):
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 54f5104c..850a1de9 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -65,14 +65,14 @@ class GIRWriter(XMLWriter):
self._write_enum(node)
elif isinstance(node, (Class, Interface)):
self._write_class(node)
- elif isinstance(node, GLibBoxed):
- self._write_boxed(node)
elif isinstance(node, Callback):
self._write_callback(node)
elif isinstance(node, Struct):
self._write_record(node)
elif isinstance(node, Union):
self._write_union(node)
+ elif isinstance(node, GLibBoxed):
+ self._write_boxed(node)
elif isinstance(node, Member):
# FIXME: atk_misc_instance singleton
pass
@@ -209,15 +209,10 @@ class GIRWriter(XMLWriter):
def _write_boxed(self, boxed):
attrs = [('c:type', boxed.ctype),
- ('glib:name', boxed.name),
- ('glib:type-name', boxed.type_name),
- ('glib:get-type', boxed.get_type)]
-
+ ('glib:name', boxed.name)]
+ attrs.extend(self._boxed_attrs(boxed))
with self.tagcontext('glib:boxed', attrs):
- for method in boxed.constructors:
- self._write_constructor(method)
- for method in boxed.methods:
- self._write_method(method)
+ self._write_boxed_ctors_methods(boxed)
def _write_property(self, prop):
attrs = [('name', prop.name)]
@@ -231,25 +226,39 @@ class GIRWriter(XMLWriter):
self._write_return_type(callback.retval)
self._write_parameters(callback.parameters)
+ def _boxed_attrs(self, boxed):
+ return [('glib:type-name', boxed.type_name),
+ ('glib:get-type', boxed.get_type)]
+
+ def _write_boxed_ctors_methods(self, boxed):
+ for method in boxed.constructors:
+ self._write_constructor(method)
+ for method in boxed.methods:
+ self._write_method(method)
+
def _write_record(self, record):
attrs = [('name', record.name),
('c:type', record.symbol)]
- if record.fields:
- with self.tagcontext('record', attrs):
+ if isinstance(record, GLibBoxed):
+ attrs.extend(self._boxed_attrs(record))
+ with self.tagcontext('record', attrs):
+ if record.fields:
for field in record.fields:
self._write_field(field)
- else:
- self.write_tag('record', attrs)
+ if isinstance(record, GLibBoxed):
+ self._write_boxed_ctors_methods(record)
def _write_union(self, union):
attrs = [('name', union.name),
('c:type', union.symbol)]
- if union.fields:
- with self.tagcontext('union', attrs):
+ if isinstance(union, GLibBoxed):
+ attrs.extend(self._boxed_attrs(union))
+ with self.tagcontext('union', attrs):
+ if union.fields:
for field in union.fields:
self._write_field(field)
- else:
- self.write_tag('union', attrs)
+ if isinstance(union, GLibBoxed):
+ self._write_boxed_ctors_methods(union)
def _write_field(self, field):
# FIXME: Just function
diff --git a/giscanner/glibast.py b/giscanner/glibast.py
index 2cdbe38d..5de98c52 100644
--- a/giscanner/glibast.py
+++ b/giscanner/glibast.py
@@ -18,7 +18,7 @@
# 02110-1301, USA.
#
-from .ast import Class, Enum, Interface, Member, Node, Property, Struct
+from .ast import Class, Enum, Interface, Member, Node, Property, Struct, Union
from .ast import (
type_names,
TYPE_STRING, TYPE_INT8, TYPE_UINT8, TYPE_INT16, TYPE_UINT16,
@@ -91,16 +91,36 @@ class GLibObject(Class):
self.ctype = ctype or type_name
-class GLibBoxed(Struct):
+class GLibBoxed:
- def __init__(self, name, type_name, get_type, ctype=None):
- Struct.__init__(self, name, get_type)
+ def __init__(self, type_name, get_type):
self.constructors = []
self.methods = []
self.type_name = type_name
self.symbol = type_name
+ self.ctype = type_name
self.get_type = get_type
- self.ctype = ctype or type_name
+
+
+class GLibBoxedStruct(Struct, GLibBoxed):
+
+ def __init__(self, name, type_name, get_type):
+ Struct.__init__(self, name, name)
+ GLibBoxed.__init__(self, type_name, get_type)
+
+
+class GLibBoxedUnion(Union, GLibBoxed):
+
+ def __init__(self, name, type_name, get_type):
+ Union.__init__(self, name, name)
+ GLibBoxed.__init__(self, type_name, get_type)
+
+
+class GLibBoxedOther(Node, GLibBoxed):
+
+ def __init__(self, name, type_name, get_type):
+ Node.__init__(self, name)
+ GLibBoxed.__init__(self, type_name, get_type)
class GLibInterface(Interface):
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 8c48a8c4..deca29b2 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -29,7 +29,8 @@ from .ast import (Callback, Enum, Function, Member, Namespace, Parameter,
Union, type_name_from_ctype)
from .transformer import Names
from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
- GLibInterface, GLibObject, GLibSignal, type_names)
+ GLibInterface, GLibObject, GLibSignal, GLibBoxedStruct,
+ GLibBoxedUnion, GLibBoxedOther, type_names)
from .utils import extract_libtool, to_underscores
@@ -65,6 +66,7 @@ class GLibTransformer(object):
self._uscore_type_names = {}
self._libraries = []
self._failed_types = {}
+ self._boxed_types = {}
self._private_internal_types = {}
self._noclosure = noclosure
self._validating = False
@@ -93,21 +95,23 @@ class GLibTransformer(object):
objectcount = count_type(GLibObject)
ifacecount = count_type(GLibInterface)
enumcount = count_type(GLibEnum)
- boxedcount = count_type(GLibBoxed)
- print " %d nodes; %d objects, %d interfaces, %d enums, %d boxed" \
- % (len(nodes), objectcount, ifacecount, enumcount, boxedcount)
+ print " %d nodes; %d objects, %d interfaces, %d enumsr" \
+ % (len(nodes), objectcount, ifacecount, enumcount)
def parse(self):
namespace = self._transformer.parse()
self._namespace_name = namespace.name
- # First pass, parsing
+ # First pass: parsing
for node in namespace.nodes:
self._parse_node(node)
# Introspection is done from within parsing
- # Second pass, delete class structures, resolve
+ # Second pass: pair boxed structures
+ for boxed in self._boxed_types.itervalues():
+ self._pair_boxed_type(boxed)
+ # Third pass: delete class structures, resolve
# all types we now know about
nodes = list(self._names.names.itervalues())
for (ns, node) in nodes:
@@ -123,7 +127,7 @@ class GLibTransformer(object):
self._resolve_alias(alias)
self._print_statistics()
- # Third pass; ensure all types are known
+ # Fourth pass: ensure all types are known
if not self._noclosure:
self._validate(nodes)
@@ -132,7 +136,6 @@ class GLibTransformer(object):
namespace.nodes = map(lambda x: x[1], self._names.aliases.itervalues())
for (ns, x) in self._names.names.itervalues():
namespace.nodes.append(x)
- print "Scan complete."
return namespace
# Private
@@ -280,7 +283,7 @@ class GLibTransformer(object):
def _name_is_internal_gtype(self, giname):
try:
node = self._get_attribute(giname)
- return isinstance(node, (GLibObject, GLibInterface, GLibBoxed,
+ return isinstance(node, (GLibObject, GLibInterface,
GLibEnum, GLibFlags))
except KeyError, e:
return False
@@ -343,7 +346,7 @@ class GLibTransformer(object):
elif isinstance(klass, (GLibEnum, GLibFlags)):
return False
elif not isinstance(tclass, (GLibObject, GLibBoxed,
- GLibInterface)):
+ GLibInterface)):
return False
else:
return True
@@ -366,9 +369,15 @@ class GLibTransformer(object):
if isinstance(klass, (GLibEnum, GLibFlags)):
return None
+ # The _uscore_type_names member holds the plain GLibBoxed
+ # object; we want to actually use the struct/record associated
+ if isinstance(klass, GLibBoxed):
+ name = self._transformer.strip_namespace_object(klass.type_name)
+ klass = self._get_attribute(name)
+
if not is_method:
# Interfaces can't have constructors, punt to global scope
- if isinstance(klass, GLibInterface):
+ if isinstance(klass, (GLibInterface, GLibBoxed)):
#print "NOTE: Rejecting constructor for"+\
# " interface type: %r" % (func.symbol, )
return None
@@ -444,14 +453,14 @@ class GLibTransformer(object):
resolved = self._transformer.strip_namespace_object(name)
pair_class = self._get_attribute(resolved)
if pair_class and isinstance(pair_class,
- (GLibObject, GLibBoxed, GLibInterface)):
+ (GLibObject, GLibInterface)):
for field in maybe_class.fields[1:]:
pair_class.fields.append(field)
return
name = self._transformer.strip_namespace_object(maybe_class.name)
pair_class = self._get_attribute(name)
if pair_class and isinstance(pair_class,
- (GLibObject, GLibBoxed, GLibInterface)):
+ (GLibObject, GLibInterface)):
del self._names.names[maybe_class.name]
@@ -541,9 +550,10 @@ class GLibTransformer(object):
def _introspect_boxed(self, type_id, symbol):
type_name = cgobject.type_name(type_id)
- node = GLibBoxed(self._transformer.strip_namespace_object(type_name),
- type_name, symbol)
- self._add_attribute(node, replace=True)
+ # This one doesn't go in the main namespace; we associate it with
+ # the struct or union
+ node = GLibBoxed(type_name, symbol)
+ self._boxed_types[node.type_name] = node
self._register_internal_type(type_name, node)
def _introspect_implemented_interfaces(self, node, type_id):
@@ -648,8 +658,6 @@ class GLibTransformer(object):
self._resolve_glib_object(node)
elif isinstance(node, GLibInterface):
self._resolve_glib_interface(node)
- elif isinstance(node, GLibBoxed):
- self._resolve_glib_boxed(node)
elif isinstance(node, Struct):
self._resolve_struct(node)
elif isinstance(node, Union):
@@ -666,6 +674,24 @@ class GLibTransformer(object):
return
self._resolve_function(newfunc)
+ def _pair_boxed_type(self, boxed):
+ name = self._transformer.strip_namespace_object(boxed.type_name)
+ pair_node = self._get_attribute(name)
+ if not pair_node:
+ boxed_item = GLibBoxedOther(name, boxed.type_name,
+ boxed.get_type)
+ elif isinstance(pair_node, Struct):
+ boxed_item = GLibBoxedStruct(pair_node.name, boxed.type_name,
+ boxed.get_type)
+ boxed_item.fields = pair_node.fields
+ elif isinstance(pair_node, Union):
+ boxed_item = GLibBoxedUnion(pair_node.name, boxed.type_name,
+ boxed.get_type)
+ boxed_item.fields = pair_node.fields
+ else:
+ return False
+ self._add_attribute(boxed_item, replace=True)
+
def _resolve_struct(self, node):
for field in node.fields:
self._resolve_field(field)
diff --git a/tests/scanner/foo-expected.gir b/tests/scanner/foo-expected.gir
index 649c5e7b..a53e778c 100644
--- a/tests/scanner/foo-expected.gir
+++ b/tests/scanner/foo-expected.gir
@@ -232,15 +232,10 @@
<member name="deux" value="2" c:identifier="FOO_ENUM_DEUX"/>
<member name="trois" value="3" c:identifier="FOO_ENUM_TROIS"/>
</enumeration>
- <glib:boxed c:type="FooBoxed"
- glib:name="Boxed"
- glib:type-name="FooBoxed"
- glib:get-type="foo_boxed_get_type">
- <constructor name="new" c:identifier="foo_boxed_new">
- <return-value>
- <type name="Boxed" c:type="FooBoxed*"/>
- </return-value>
- </constructor>
+ <record name="Boxed"
+ c:type="FooBoxed"
+ glib:type-name="FooBoxed"
+ glib:get-type="foo_boxed_get_type">
<method name="method" c:identifier="foo_boxed_method">
<return-value>
<type name="none" c:type="void"/>
@@ -251,7 +246,12 @@
</parameter>
</parameters>
</method>
- </glib:boxed>
+ </record>
+ <function name="boxed_new" c:identifier="foo_boxed_new">
+ <return-value>
+ <type name="Boxed" c:type="FooBoxed*"/>
+ </return-value>
+ </function>
<callback name="Callback" c:type="FooCallback">
<return-value>
<type name="boolean" c:type="gboolean"/>
@@ -276,7 +276,8 @@
<type name="int" c:type="int"/>
</field>
</record>
- <record name="StructPrivate" c:type="FooStructPrivate"/>
+ <record name="StructPrivate" c:type="FooStructPrivate">
+ </record>
<record name="Rectangle" c:type="FooRectangle">
<field name="x">
<type name="int" c:type="gint"/>
diff --git a/tests/scanner/utility-expected.gir b/tests/scanner/utility-expected.gir
index 7e262e1f..9735675a 100644
--- a/tests/scanner/utility-expected.gir
+++ b/tests/scanner/utility-expected.gir
@@ -27,6 +27,7 @@
<member name="b" value="1" c:identifier="UTILITY_FLAG_B"/>
<member name="c" value="2" c:identifier="UTILITY_FLAG_C"/>
</enumeration>
- <record name="Struct" c:type="UtilityStruct"/>
+ <record name="Struct" c:type="UtilityStruct">
+ </record>
</namespace>
</repository>
diff --git a/tools/generate.c b/tools/generate.c
index 2f6f512e..efa4e7a7 100644
--- a/tools/generate.c
+++ b/tools/generate.c
@@ -413,15 +413,18 @@ write_struct_info (const gchar *namespace,
name = g_base_info_get_name ((GIBaseInfo *)info);
deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
+ type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
+ type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
+
if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_BOXED)
{
- type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
- type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
-
- g_fprintf (file, " <glib:boxed glib:name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"", name, type_name, type_init);
+ g_fprintf (file, " <glib:boxed glib:name=\"%s\"", name);
}
else
g_fprintf (file, " <record name=\"%s\"", name);
+
+ if (type_name != NULL)
+ g_fprintf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
if (deprecated)
g_fprintf (file, " deprecated=\"1\"");