diff --git a/girnode.c b/girnode.c index fd74dd9ff..2c557b5c7 100644 --- a/girnode.c +++ b/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/girnode.h b/girnode.h index 6079d367a..67027aecc 100644 --- a/girnode.h +++ b/girnode.h @@ -272,6 +272,9 @@ struct _GIrNodeStruct GIrNode node; gboolean deprecated; + + gchar *gtype_name; + gchar *gtype_init; GList *members; }; diff --git a/girparser.c b/girparser.c index 11152d84f..980d58d45 100644 --- a/girparser.c +++ b/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_; - - 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); + 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_->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/gtypelib.c b/gtypelib.c index 3940a329d..50abcb57e 100644 --- a/gtypelib.c +++ b/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;