mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
Add copy and free function annotations for POD types
Plain Old Data (POD) types with or without a representation in the GType type system can still have a copy and/or a free function. We should allow annotating these types with their corresponding functions for copying their data into a new instance, and freeing their data. From a language bindings perspective, POD types should have a boxed GType wrapper around them, so they can use the generic GBoxed API to copy and free instances; from a documentation perspective, though, it'd be good to have a way to match a structured type, like a struct or a union, with its copy and free functions. In order to do that, we add two new header block annotations: - (copy-func function_name) - (free-func function_name) These annotations work exactly like ref-func and unref-func for typed instances: /** * GdkRGBA: (copy-func gdk_rgba_copy) * (free-func gdk_rgba_free) * @red: ... * @green: ... * @blue: ... * @alpha: ... * * ... */ The function is stored in the GIR data as two new attributes for the `<record>` and `<union>` elements: <record name="RGBA" c:type="GdkRGBA" copy-function="gdk_rgba_copy" free-function="gdk_rgba_free" glib:type-name="GdkRGBA" glib:get-type="gdk_rgba_get_type" c:symbol-prefix="gdk_rgba"> The annotations are not mandatory. See: #14
This commit is contained in:
parent
47b674d30f
commit
605fdf7046
22
girnode.c
22
girnode.c
@ -370,6 +370,8 @@ _g_ir_node_free (GIrNode *node)
|
||||
g_free (node->name);
|
||||
g_free (struct_->gtype_name);
|
||||
g_free (struct_->gtype_init);
|
||||
g_free (struct_->copy_func);
|
||||
g_free (struct_->free_func);
|
||||
|
||||
for (l = struct_->members; l; l = l->next)
|
||||
_g_ir_node_free ((GIrNode *)l->data);
|
||||
@ -403,6 +405,8 @@ _g_ir_node_free (GIrNode *node)
|
||||
g_free (node->name);
|
||||
g_free (union_->gtype_name);
|
||||
g_free (union_->gtype_init);
|
||||
g_free (union_->copy_func);
|
||||
g_free (union_->free_func);
|
||||
|
||||
_g_ir_node_free ((GIrNode *)union_->discriminator_type);
|
||||
for (l = union_->members; l; l = l->next)
|
||||
@ -755,6 +759,10 @@ _g_ir_node_get_full_size_internal (GIrNode *parent,
|
||||
size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4);
|
||||
if (struct_->gtype_init)
|
||||
size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4);
|
||||
if (struct_->copy_func)
|
||||
size += ALIGN_VALUE (strlen (struct_->copy_func) + 1, 4);
|
||||
if (struct_->free_func)
|
||||
size += ALIGN_VALUE (strlen (struct_->free_func) + 1, 4);
|
||||
for (l = struct_->members; l; l = l->next)
|
||||
size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
|
||||
}
|
||||
@ -855,6 +863,10 @@ _g_ir_node_get_full_size_internal (GIrNode *parent,
|
||||
size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4);
|
||||
if (union_->gtype_init)
|
||||
size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4);
|
||||
if (union_->copy_func)
|
||||
size += ALIGN_VALUE (strlen (union_->copy_func) + 1, 4);
|
||||
if (union_->free_func)
|
||||
size += ALIGN_VALUE (strlen (union_->free_func) + 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)
|
||||
@ -1956,6 +1968,11 @@ _g_ir_node_build_typelib (GIrNode *node,
|
||||
blob->gtype_init = 0;
|
||||
}
|
||||
|
||||
if (struct_->copy_func)
|
||||
blob->copy_func = _g_ir_write_string (struct_->copy_func, strings, data, offset2);
|
||||
if (struct_->free_func)
|
||||
blob->free_func = _g_ir_write_string (struct_->free_func, strings, data, offset2);
|
||||
|
||||
blob->n_fields = 0;
|
||||
blob->n_methods = 0;
|
||||
|
||||
@ -2040,6 +2057,11 @@ _g_ir_node_build_typelib (GIrNode *node,
|
||||
|
||||
blob->discriminator_offset = union_->discriminator_offset;
|
||||
|
||||
if (union_->copy_func)
|
||||
blob->copy_func = _g_ir_write_string (union_->copy_func, strings, data, offset2);
|
||||
if (union_->free_func)
|
||||
blob->free_func = _g_ir_write_string (union_->free_func, strings, data, offset2);
|
||||
|
||||
/* We don't support Union discriminators right now. */
|
||||
/*
|
||||
if (union_->discriminator_type)
|
||||
|
@ -328,6 +328,9 @@ struct _GIrNodeStruct
|
||||
gchar *gtype_name;
|
||||
gchar *gtype_init;
|
||||
|
||||
gchar *copy_func;
|
||||
gchar *free_func;
|
||||
|
||||
gint alignment;
|
||||
gint size;
|
||||
|
||||
@ -346,6 +349,9 @@ struct _GIrNodeUnion
|
||||
gchar *gtype_name;
|
||||
gchar *gtype_init;
|
||||
|
||||
gchar *copy_func;
|
||||
gchar *free_func;
|
||||
|
||||
gint alignment;
|
||||
gint size;
|
||||
|
||||
|
17
girparser.c
17
girparser.c
@ -477,7 +477,9 @@ parse_basic (const char *str)
|
||||
|
||||
static GIrNodeType *
|
||||
parse_type_internal (GIrModule *module,
|
||||
const gchar *str, char **next, gboolean in_glib,
|
||||
const gchar *str,
|
||||
char **next,
|
||||
gboolean in_glib,
|
||||
gboolean in_gobject)
|
||||
{
|
||||
const BasicTypeInfo *basic;
|
||||
@ -2560,6 +2562,8 @@ start_struct (GMarkupParseContext *context,
|
||||
const gchar *gtype_init;
|
||||
const gchar *gtype_struct;
|
||||
const gchar *foreign;
|
||||
const gchar *copy_func;
|
||||
const gchar *free_func;
|
||||
GIrNodeStruct *struct_;
|
||||
|
||||
if (!(strcmp (element_name, "record") == 0 &&
|
||||
@ -2579,6 +2583,8 @@ start_struct (GMarkupParseContext *context,
|
||||
gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
|
||||
gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values);
|
||||
foreign = find_attribute ("foreign", attribute_names, attribute_values);
|
||||
copy_func = find_attribute ("copy-function", attribute_names, attribute_values);
|
||||
free_func = find_attribute ("free-function", attribute_names, attribute_values);
|
||||
|
||||
if (name == NULL && ctx->node_stack == NULL)
|
||||
{
|
||||
@ -2615,6 +2621,9 @@ start_struct (GMarkupParseContext *context,
|
||||
|
||||
struct_->foreign = (g_strcmp0 (foreign, "1") == 0);
|
||||
|
||||
struct_->copy_func = g_strdup (copy_func);
|
||||
struct_->free_func = g_strdup (free_func);
|
||||
|
||||
if (ctx->node_stack == NULL)
|
||||
ctx->current_module->entries =
|
||||
g_list_append (ctx->current_module->entries, struct_);
|
||||
@ -2634,6 +2643,8 @@ start_union (GMarkupParseContext *context,
|
||||
const gchar *deprecated;
|
||||
const gchar *typename;
|
||||
const gchar *typeinit;
|
||||
const gchar *copy_func;
|
||||
const gchar *free_func;
|
||||
GIrNodeUnion *union_;
|
||||
|
||||
if (!(strcmp (element_name, "union") == 0 &&
|
||||
@ -2650,6 +2661,8 @@ start_union (GMarkupParseContext *context,
|
||||
deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
|
||||
typename = find_attribute ("glib:type-name", attribute_names, attribute_values);
|
||||
typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
|
||||
copy_func = find_attribute ("copy-function", attribute_names, attribute_values);
|
||||
free_func = find_attribute ("free-function", attribute_names, attribute_values);
|
||||
|
||||
if (name == NULL && ctx->node_stack == NULL)
|
||||
{
|
||||
@ -2663,6 +2676,8 @@ start_union (GMarkupParseContext *context,
|
||||
((GIrNode *)union_)->name = g_strdup (name ? name : "");
|
||||
union_->gtype_name = g_strdup (typename);
|
||||
union_->gtype_init = g_strdup (typeinit);
|
||||
union_->copy_func = g_strdup (copy_func);
|
||||
union_->free_func = g_strdup (free_func);
|
||||
if (deprecated)
|
||||
union_->deprecated = TRUE;
|
||||
else
|
||||
|
18
girwriter.c
18
girwriter.c
@ -642,6 +642,7 @@ write_struct_info (const gchar *namespace,
|
||||
const gchar *name;
|
||||
const gchar *type_name;
|
||||
const gchar *type_init;
|
||||
const gchar *func;
|
||||
gboolean deprecated;
|
||||
gboolean is_gtype_struct;
|
||||
gboolean foreign;
|
||||
@ -676,6 +677,14 @@ write_struct_info (const gchar *namespace,
|
||||
if (is_gtype_struct)
|
||||
xml_printf (file, " glib:is-gtype-struct=\"1\"");
|
||||
|
||||
func = g_struct_info_get_copy_function (info);
|
||||
if (func)
|
||||
xml_printf (file, " copy-function=\"%s\"", func);
|
||||
|
||||
func = g_struct_info_get_free_function (info);
|
||||
if (func)
|
||||
xml_printf (file, " free-function=\"%s\"", func);
|
||||
|
||||
write_attributes (file, (GIBaseInfo*) info);
|
||||
|
||||
size = g_struct_info_get_size (info);
|
||||
@ -1237,6 +1246,7 @@ write_union_info (const gchar *namespace,
|
||||
const gchar *name;
|
||||
const gchar *type_name;
|
||||
const gchar *type_init;
|
||||
const gchar *func;
|
||||
gboolean deprecated;
|
||||
gint i;
|
||||
gint size;
|
||||
@ -1260,6 +1270,14 @@ write_union_info (const gchar *namespace,
|
||||
if (file->show_all && size >= 0)
|
||||
xml_printf (file, " size=\"%d\"", size);
|
||||
|
||||
func = g_union_info_get_copy_function (info);
|
||||
if (func)
|
||||
xml_printf (file, " copy-function=\"%s\"", func);
|
||||
|
||||
func = g_union_info_get_free_function (info);
|
||||
if (func)
|
||||
xml_printf (file, " free-function=\"%s\"", func);
|
||||
|
||||
write_attributes (file, (GIBaseInfo*) info);
|
||||
|
||||
if (g_union_info_is_discriminated (info))
|
||||
|
@ -281,3 +281,57 @@ g_struct_info_is_gtype_struct (GIStructInfo *info)
|
||||
|
||||
return blob->is_gtype_struct;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_struct_info_get_copy_function:
|
||||
* @info: a struct information blob
|
||||
*
|
||||
* Retrieves the name of the copy function for @info, if any is set.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the name of the copy function
|
||||
*
|
||||
* Since: 1.76
|
||||
*/
|
||||
const char *
|
||||
g_struct_info_get_copy_function (GIStructInfo *info)
|
||||
{
|
||||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||||
StructBlob *blob;
|
||||
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
g_return_val_if_fail (GI_IS_STRUCT_INFO (info), NULL);
|
||||
|
||||
blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
if (blob->copy_func)
|
||||
return g_typelib_get_string (rinfo->typelib, blob->copy_func);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_struct_info_get_free_function:
|
||||
* @info: a struct information blob
|
||||
*
|
||||
* Retrieves the name of the free function for @info, if any is set.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the name of the free function
|
||||
*
|
||||
* Since: 1.76
|
||||
*/
|
||||
const char *
|
||||
g_struct_info_get_free_function (GIStructInfo *info)
|
||||
{
|
||||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||||
StructBlob *blob;
|
||||
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
g_return_val_if_fail (GI_IS_STRUCT_INFO (info), NULL);
|
||||
|
||||
blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
if (blob->free_func)
|
||||
return g_typelib_get_string (rinfo->typelib, blob->free_func);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -75,7 +75,12 @@ gboolean g_struct_info_is_gtype_struct (GIStructInfo *info);
|
||||
GI_AVAILABLE_IN_ALL
|
||||
gboolean g_struct_info_is_foreign (GIStructInfo *info);
|
||||
|
||||
GI_AVAILABLE_IN_1_76
|
||||
const char * g_struct_info_get_copy_function (GIStructInfo *info);
|
||||
|
||||
GI_AVAILABLE_IN_1_76
|
||||
const char * g_struct_info_get_free_function (GIStructInfo *info);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif /* __GISTRUCTINFO_H__ */
|
||||
|
@ -792,8 +792,10 @@ typedef struct {
|
||||
* @size: The size of the struct in bytes.
|
||||
* @n_fields: TODO
|
||||
* @n_methods: TODO
|
||||
* @reserved2: Reserved for future use.
|
||||
* @reserved3: Reserved for future use.
|
||||
* @copy_func: String pointing to a function which can be called to copy
|
||||
* the contents of this struct type
|
||||
* @free_func: String pointing to a function which can be called to free
|
||||
* the contents of this struct type
|
||||
*
|
||||
* TODO
|
||||
*/
|
||||
@ -817,8 +819,8 @@ typedef struct {
|
||||
guint16 n_fields;
|
||||
guint16 n_methods;
|
||||
|
||||
guint32 reserved2;
|
||||
guint32 reserved3;
|
||||
guint32 copy_func;
|
||||
guint32 free_func;
|
||||
} StructBlob;
|
||||
|
||||
/**
|
||||
@ -835,8 +837,10 @@ typedef struct {
|
||||
* @size: TODO
|
||||
* @n_fields: Length of the arrays
|
||||
* @n_functions: TODO
|
||||
* @reserved2: Reserved for future use.
|
||||
* @reserved3: Reserved for future use.
|
||||
* @copy_func: String pointing to a function which can be called to copy
|
||||
* the contents of this union type
|
||||
* @free_func: String pointing to a function which can be called to free
|
||||
* the contents of this union type
|
||||
* @discriminator_offset: Offset from the beginning of the union where the
|
||||
* discriminator of a discriminated union is located. The value 0xFFFF
|
||||
* indicates that the discriminator offset is unknown.
|
||||
@ -861,8 +865,8 @@ typedef struct {
|
||||
guint16 n_fields;
|
||||
guint16 n_functions;
|
||||
|
||||
guint32 reserved2;
|
||||
guint32 reserved3;
|
||||
guint32 copy_func;
|
||||
guint32 free_func;
|
||||
|
||||
gint32 discriminator_offset;
|
||||
SimpleTypeBlob discriminator_type;
|
||||
|
@ -267,3 +267,57 @@ g_union_info_get_alignment (GIUnionInfo *info)
|
||||
|
||||
return blob->alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_union_info_get_copy_function:
|
||||
* @info: a union information blob
|
||||
*
|
||||
* Retrieves the name of the copy function for @info, if any is set.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the name of the copy function
|
||||
*
|
||||
* Since: 1.76
|
||||
*/
|
||||
const char *
|
||||
g_union_info_get_copy_function (GIUnionInfo *info)
|
||||
{
|
||||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||||
UnionBlob *blob;
|
||||
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
g_return_val_if_fail (GI_IS_UNION_INFO (info), NULL);
|
||||
|
||||
blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
if (blob->copy_func)
|
||||
return g_typelib_get_string (rinfo->typelib, blob->copy_func);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_union_info_get_free_function:
|
||||
* @info: a union information blob
|
||||
*
|
||||
* Retrieves the name of the free function for @info, if any is set.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the name of the free function
|
||||
*
|
||||
* Since: 1.76
|
||||
*/
|
||||
const char *
|
||||
g_union_info_get_free_function (GIUnionInfo *info)
|
||||
{
|
||||
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||||
UnionBlob *blob;
|
||||
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
g_return_val_if_fail (GI_IS_UNION_INFO (info), NULL);
|
||||
|
||||
blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
|
||||
|
||||
if (blob->free_func)
|
||||
return g_typelib_get_string (rinfo->typelib, blob->free_func);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -77,6 +77,12 @@ gsize g_union_info_get_size (GIUnionInfo *info);
|
||||
GI_AVAILABLE_IN_ALL
|
||||
gsize g_union_info_get_alignment (GIUnionInfo *info);
|
||||
|
||||
GI_AVAILABLE_IN_1_76
|
||||
const char * g_union_info_get_copy_function (GIUnionInfo *info);
|
||||
|
||||
GI_AVAILABLE_IN_1_76
|
||||
const char * g_union_info_get_free_function (GIUnionInfo *info);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user