mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-16 12:28:48 +02:00
Allow attributes on parameters and return values
Any annotation where the key has a dot in the name will go into the attribute list. For example * @arg: (foo.bar baz): some arg the parameter @arg will get the attribute with key foo.bar and value baz. This also works for. * Returns: (foo.bar2 baz2): the return value Also add tests for this new feature. See https://bugzilla.gnome.org/show_bug.cgi?id=571548 Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
parent
c57c9efe6f
commit
3d0dc7d214
24
gibaseinfo.c
24
gibaseinfo.c
@ -475,7 +475,7 @@ g_base_info_get_attribute (GIBaseInfo *info,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
cmp_attribute (const void *av,
|
cmp_attribute (const void *av,
|
||||||
const void *bv)
|
const void *bv)
|
||||||
{
|
{
|
||||||
const AttributeBlob *a = av;
|
const AttributeBlob *a = av;
|
||||||
const AttributeBlob *b = bv;
|
const AttributeBlob *b = bv;
|
||||||
@ -488,13 +488,25 @@ cmp_attribute (const void *av,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AttributeBlob *
|
/*
|
||||||
find_first_attribute (GIRealInfo *rinfo)
|
* _attribute_blob_find_first:
|
||||||
|
* @GIBaseInfo: A #GIBaseInfo.
|
||||||
|
* @blob_offset: The offset for the blob to find the first attribute for.
|
||||||
|
*
|
||||||
|
* Searches for the first #AttributeBlob for @blob_offset and returns
|
||||||
|
* it if found.
|
||||||
|
*
|
||||||
|
* Returns: A pointer to #AttributeBlob or %NULL if not found.
|
||||||
|
*/
|
||||||
|
AttributeBlob *
|
||||||
|
_attribute_blob_find_first (GIBaseInfo *info,
|
||||||
|
guint32 blob_offset)
|
||||||
{
|
{
|
||||||
|
GIRealInfo *rinfo = (GIRealInfo *) info;
|
||||||
Header *header = (Header *)rinfo->typelib->data;
|
Header *header = (Header *)rinfo->typelib->data;
|
||||||
AttributeBlob blob, *first, *res, *previous;
|
AttributeBlob blob, *first, *res, *previous;
|
||||||
|
|
||||||
blob.offset = rinfo->offset;
|
blob.offset = blob_offset;
|
||||||
|
|
||||||
first = (AttributeBlob *) &rinfo->typelib->data[header->attributes];
|
first = (AttributeBlob *) &rinfo->typelib->data[header->attributes];
|
||||||
|
|
||||||
@ -505,7 +517,7 @@ find_first_attribute (GIRealInfo *rinfo)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
previous = res - 1;
|
previous = res - 1;
|
||||||
while (previous >= first && previous->offset == rinfo->offset)
|
while (previous >= first && previous->offset == blob_offset)
|
||||||
{
|
{
|
||||||
res = previous;
|
res = previous;
|
||||||
previous = res - 1;
|
previous = res - 1;
|
||||||
@ -563,7 +575,7 @@ g_base_info_iterate_attributes (GIBaseInfo *info,
|
|||||||
if (iterator->data != NULL)
|
if (iterator->data != NULL)
|
||||||
next = (AttributeBlob *) iterator->data;
|
next = (AttributeBlob *) iterator->data;
|
||||||
else
|
else
|
||||||
next = find_first_attribute (rinfo);
|
next = _attribute_blob_find_first (info, rinfo->offset);
|
||||||
|
|
||||||
if (next == NULL || next->offset != rinfo->offset || next >= after)
|
if (next == NULL || next->offset != rinfo->offset || next >= after)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include <girepository.h>
|
#include <girepository.h>
|
||||||
@ -259,3 +261,77 @@ g_callable_info_load_arg (GICallableInfo *info,
|
|||||||
_g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib,
|
_g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib,
|
||||||
offset + header->signature_blob_size + n * header->arg_blob_size);
|
offset + header->signature_blob_size + n * header->arg_blob_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_callable_info_get_return_attribute:
|
||||||
|
* @info: a #GICallableInfo
|
||||||
|
* @name: a freeform string naming an attribute
|
||||||
|
*
|
||||||
|
* Retrieve an arbitrary attribute associated with the return value.
|
||||||
|
*
|
||||||
|
* Returns: The value of the attribute, or %NULL if no such attribute exists
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
g_callable_info_get_return_attribute (GICallableInfo *info,
|
||||||
|
const gchar *name)
|
||||||
|
{
|
||||||
|
GIAttributeIter iter = { 0, };
|
||||||
|
gchar *curname, *curvalue;
|
||||||
|
while (g_callable_info_iterate_return_attributes (info, &iter, &curname, &curvalue))
|
||||||
|
{
|
||||||
|
if (g_strcmp0 (name, curname) == 0)
|
||||||
|
return (const gchar*) curvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_callable_info_iterate_return_attributes:
|
||||||
|
* @info: a #GICallableInfo
|
||||||
|
* @iterator: a #GIAttributeIter structure, must be initialized; see below
|
||||||
|
* @name: (out) (transfer none): Returned name, must not be freed
|
||||||
|
* @value: (out) (transfer none): Returned name, must not be freed
|
||||||
|
*
|
||||||
|
* Iterate over all attributes associated with the return value. The
|
||||||
|
* iterator structure is typically stack allocated, and must have its
|
||||||
|
* first member initialized to %NULL.
|
||||||
|
*
|
||||||
|
* Both the @name and @value should be treated as constants
|
||||||
|
* and must not be freed.
|
||||||
|
*
|
||||||
|
* See g_base_info_iterate_attributes() for an example of how to use a
|
||||||
|
* similar API.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if there are more attributes
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
g_callable_info_iterate_return_attributes (GICallableInfo *info,
|
||||||
|
GIAttributeIter *iterator,
|
||||||
|
char **name,
|
||||||
|
char **value)
|
||||||
|
{
|
||||||
|
GIRealInfo *rinfo = (GIRealInfo *)info;
|
||||||
|
Header *header = (Header *)rinfo->typelib->data;
|
||||||
|
AttributeBlob *next, *after;
|
||||||
|
guint32 blob_offset;
|
||||||
|
|
||||||
|
after = (AttributeBlob *) &rinfo->typelib->data[header->attributes +
|
||||||
|
header->n_attributes * header->attribute_blob_size];
|
||||||
|
|
||||||
|
blob_offset = signature_offset (info);
|
||||||
|
|
||||||
|
if (iterator->data != NULL)
|
||||||
|
next = (AttributeBlob *) iterator->data;
|
||||||
|
else
|
||||||
|
next = _attribute_blob_find_first (info, blob_offset);
|
||||||
|
|
||||||
|
if (next == NULL || next->offset != blob_offset || next >= after)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*name = (gchar*) g_typelib_get_string (rinfo->typelib, next->name);
|
||||||
|
*value = (gchar*) g_typelib_get_string (rinfo->typelib, next->value);
|
||||||
|
iterator->data = next + 1;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
@ -39,6 +39,12 @@ G_BEGIN_DECLS
|
|||||||
GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info);
|
GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info);
|
||||||
void g_callable_info_load_return_type (GICallableInfo *info,
|
void g_callable_info_load_return_type (GICallableInfo *info,
|
||||||
GITypeInfo *type);
|
GITypeInfo *type);
|
||||||
|
const gchar * g_callable_info_get_return_attribute (GICallableInfo *info,
|
||||||
|
const gchar *name);
|
||||||
|
gboolean g_callable_info_iterate_return_attributes (GICallableInfo *info,
|
||||||
|
GIAttributeIter *iterator,
|
||||||
|
char **name,
|
||||||
|
char **value);
|
||||||
GITransfer g_callable_info_get_caller_owns (GICallableInfo *info);
|
GITransfer g_callable_info_get_caller_owns (GICallableInfo *info);
|
||||||
gboolean g_callable_info_may_return_null (GICallableInfo *info);
|
gboolean g_callable_info_may_return_null (GICallableInfo *info);
|
||||||
gint g_callable_info_get_n_args (GICallableInfo *info);
|
gint g_callable_info_get_n_args (GICallableInfo *info);
|
||||||
|
16
girnode.c
16
girnode.c
@ -1678,6 +1678,14 @@ g_ir_node_build_typelib (GIrNode *node,
|
|||||||
blob->symbol = write_string (function->symbol, strings, data, offset2);
|
blob->symbol = write_string (function->symbol, strings, data, offset2);
|
||||||
blob->signature = signature;
|
blob->signature = signature;
|
||||||
|
|
||||||
|
/* function->result is special since it doesn't appear in the serialized format but
|
||||||
|
* we do want the attributes for it to appear
|
||||||
|
*/
|
||||||
|
build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, function->result);
|
||||||
|
build->n_attributes += g_hash_table_size (((GIrNode *) function->result)->attributes);
|
||||||
|
g_assert (((GIrNode *) function->result)->offset == 0);
|
||||||
|
((GIrNode *) function->result)->offset = signature;
|
||||||
|
|
||||||
g_debug ("building function '%s'", function->symbol);
|
g_debug ("building function '%s'", function->symbol);
|
||||||
|
|
||||||
g_ir_node_build_typelib ((GIrNode *)function->result->type,
|
g_ir_node_build_typelib ((GIrNode *)function->result->type,
|
||||||
@ -1770,6 +1778,14 @@ g_ir_node_build_typelib (GIrNode *node,
|
|||||||
blob->name = write_string (node->name, strings, data, offset2);
|
blob->name = write_string (node->name, strings, data, offset2);
|
||||||
blob->signature = signature;
|
blob->signature = signature;
|
||||||
|
|
||||||
|
/* signal->result is special since it doesn't appear in the serialized format but
|
||||||
|
* we do want the attributes for it to appear
|
||||||
|
*/
|
||||||
|
build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, signal->result);
|
||||||
|
build->n_attributes += g_hash_table_size (((GIrNode *) signal->result)->attributes);
|
||||||
|
g_assert (((GIrNode *) signal->result)->offset == 0);
|
||||||
|
((GIrNode *) signal->result)->offset = signature;
|
||||||
|
|
||||||
g_ir_node_build_typelib ((GIrNode *)signal->result->type,
|
g_ir_node_build_typelib ((GIrNode *)signal->result->type,
|
||||||
node, build, &signature, offset2);
|
node, build, &signature, offset2);
|
||||||
|
|
||||||
|
@ -1990,7 +1990,14 @@ start_attribute (GMarkupParseContext *context,
|
|||||||
|
|
||||||
curnode = CURRENT_NODE (ctx);
|
curnode = CURRENT_NODE (ctx);
|
||||||
|
|
||||||
g_hash_table_insert (curnode->attributes, g_strdup (name), g_strdup (value));
|
if (ctx->current_typed && ctx->current_typed->type == G_IR_NODE_PARAM)
|
||||||
|
{
|
||||||
|
g_hash_table_insert (ctx->current_typed->attributes, g_strdup (name), g_strdup (value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_hash_table_insert (curnode->attributes, g_strdup (name), g_strdup (value));
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
21
girwriter.c
21
girwriter.c
@ -358,7 +358,7 @@ write_type_info (const gchar *namespace,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
write_attributes (Xml *file,
|
write_attributes (Xml *file,
|
||||||
GIBaseInfo *info)
|
GIBaseInfo *info)
|
||||||
{
|
{
|
||||||
GIAttributeIter iter = { 0, };
|
GIAttributeIter iter = { 0, };
|
||||||
char *name, *value;
|
char *name, *value;
|
||||||
@ -371,6 +371,21 @@ write_attributes (Xml *file,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_return_value_attributes (Xml *file,
|
||||||
|
GICallableInfo *info)
|
||||||
|
{
|
||||||
|
GIAttributeIter iter = { 0, };
|
||||||
|
char *name, *value;
|
||||||
|
|
||||||
|
while (g_callable_info_iterate_return_attributes (info, &iter, &name, &value))
|
||||||
|
{
|
||||||
|
xml_start_element (file, "attribute");
|
||||||
|
xml_printf (file, " name=\"%s\" value=\"%s\"", name, value);
|
||||||
|
xml_end_element (file, "attribute");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_constant_value (const gchar *namespace,
|
write_constant_value (const gchar *namespace,
|
||||||
GITypeInfo *info,
|
GITypeInfo *info,
|
||||||
@ -467,6 +482,8 @@ write_callable_info (const gchar *namespace,
|
|||||||
if (g_callable_info_may_return_null (info))
|
if (g_callable_info_may_return_null (info))
|
||||||
xml_printf (file, " allow-none=\"1\"");
|
xml_printf (file, " allow-none=\"1\"");
|
||||||
|
|
||||||
|
write_return_value_attributes (file, info);
|
||||||
|
|
||||||
write_type_info (namespace, type, file);
|
write_type_info (namespace, type, file);
|
||||||
|
|
||||||
xml_end_element (file, "return-value");
|
xml_end_element (file, "return-value");
|
||||||
@ -528,6 +545,8 @@ write_callable_info (const gchar *namespace,
|
|||||||
if (g_arg_info_get_destroy (arg) >= 0)
|
if (g_arg_info_get_destroy (arg) >= 0)
|
||||||
xml_printf (file, " destroy=\"%d\"", g_arg_info_get_destroy (arg));
|
xml_printf (file, " destroy=\"%d\"", g_arg_info_get_destroy (arg));
|
||||||
|
|
||||||
|
write_attributes (file, (GIBaseInfo*) arg);
|
||||||
|
|
||||||
type = g_arg_info_get_type (arg);
|
type = g_arg_info_get_type (arg);
|
||||||
write_type_info (namespace, type, file);
|
write_type_info (namespace, type, file);
|
||||||
|
|
||||||
|
@ -1110,6 +1110,10 @@ gboolean g_typelib_validate (GTypelib *typelib,
|
|||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
|
||||||
|
/* defined in gibaseinfo.c */
|
||||||
|
AttributeBlob *_attribute_blob_find_first (GIBaseInfo *info,
|
||||||
|
guint32 blob_offset);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __G_TYPELIB_H__ */
|
#endif /* __G_TYPELIB_H__ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user