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
This commit is contained in:
Colin Walters 2008-09-06 20:33:51 +00:00
parent 71473eb033
commit 8f09203dda
4 changed files with 62 additions and 32 deletions

View File

@ -339,6 +339,9 @@ g_ir_node_free (GIrNode *node)
GIrNodeStruct *struct_ = (GIrNodeStruct *)node; GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
g_free (node->name); g_free (node->name);
g_free (struct_->gtype_name);
g_free (struct_->gtype_init);
for (l = struct_->members; l; l = l->next) for (l = struct_->members; l; l = l->next)
g_ir_node_free ((GIrNode *)l->data); g_ir_node_free ((GIrNode *)l->data);
g_list_free (struct_->members); g_list_free (struct_->members);
@ -706,6 +709,10 @@ g_ir_node_get_full_size_internal (GIrNode *parent,
size = 20; size = 20;
size += ALIGN_VALUE (strlen (node->name) + 1, 4); 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) for (l = struct_->members; l; l = l->next)
size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); 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 = 28;
size += ALIGN_VALUE (strlen (node->name) + 1, 4); 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) for (l = union_->members; l; l = l->next)
size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
for (l = union_->discriminators; l; l = l->next) 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->blob_type = BLOB_TYPE_STRUCT;
blob->deprecated = struct_->deprecated; blob->deprecated = struct_->deprecated;
blob->unregistered = TRUE;
blob->reserved = 0; blob->reserved = 0;
blob->name = write_string (node->name, strings, data, offset2); blob->name = write_string (node->name, strings, data, offset2);
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_name = 0;
blob->gtype_init = 0; blob->gtype_init = 0;
}
blob->n_fields = 0; blob->n_fields = 0;
blob->n_methods = 0; blob->n_methods = 0;

View File

@ -273,6 +273,9 @@ struct _GIrNodeStruct
gboolean deprecated; gboolean deprecated;
gchar *gtype_name;
gchar *gtype_init;
GList *members; GList *members;
}; };

View File

@ -1889,15 +1889,30 @@ start_struct (GMarkupParseContext *context,
{ {
const gchar *name; const gchar *name;
const gchar *deprecated; const gchar *deprecated;
const gchar *gtype_name;
const gchar *gtype_init;
GIrNodeStruct *struct_;
name = find_attribute ("name", attribute_names, attribute_values); name = find_attribute ("name", attribute_names, attribute_values);
deprecated = find_attribute ("deprecated", 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) 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); struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
@ -1907,12 +1922,14 @@ start_struct (GMarkupParseContext *context,
else else
struct_->deprecated = FALSE; struct_->deprecated = FALSE;
struct_->gtype_name = g_strdup (gtype_name);
struct_->gtype_init = g_strdup (gtype_init);
ctx->current_node = (GIrNode *)struct_; ctx->current_node = (GIrNode *)struct_;
ctx->current_module->entries = ctx->current_module->entries =
g_list_append (ctx->current_module->entries, struct_); g_list_append (ctx->current_module->entries, struct_);
state_switch (ctx, STATE_STRUCT); state_switch (ctx, STATE_STRUCT);
}
return TRUE; return TRUE;
} }
return FALSE; return FALSE;

View File

@ -1174,22 +1174,12 @@ validate_struct_blob (ValidateContext *ctx,
return FALSE; 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)) if (!validate_name (typelib, "struct", typelib->data, blob->name, error))
return FALSE; return FALSE;
push_context (ctx, get_string_nofail (typelib, blob->name)); 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)) if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_name, error))
return FALSE; return FALSE;