Support (out caller-allocates)

People have wanted support for marking (out) on functions of the
form:

/**
 * clutter_color_from_pixel:
 * @pixel: A pixel
 * @color: (out): Color to initialize with value of @pixel
 */
void
clutter_color_from_pixel (guint32 pixel, ClutterColor *color);

Where the caller is supposed to have allocated the argument; the
C function just initializes it.  This patch adds support for this
argument passing style to introspection.  In this case, we see the
(out), and notice that there's only a single indirection (*) on
the argument, and assume that this means (out caller-allocates).

https://bugzilla.gnome.org/show_bug.cgi?id=604749
This commit is contained in:
Colin Walters 2009-12-16 11:47:19 -05:00
parent 9505b6eb44
commit 46d9ef151e
6 changed files with 26 additions and 17 deletions

12
ginfo.c
View File

@ -1021,21 +1021,23 @@ g_arg_info_is_return_value (GIArgInfo *info)
}
/**
* g_arg_info_is_dipper:
* g_arg_info_is_caller_allocates:
* @info: a #GIArgInfo
*
* Obtain if the argument is a pointer to a struct or object that will
* receive an output of a function.
* receive an output of a function. The default assumption for
* %GI_DIRECTION_OUT arguments which have allocation is that the
* callee allocates; if this is %TRUE, then the caller must allocate.
*
* Returns: %TRUE if it is a dipper argument
* Returns: %TRUE if caller is required to have allocated the argument
*/
gboolean
g_arg_info_is_dipper (GIArgInfo *info)
g_arg_info_is_caller_allocates (GIArgInfo *info)
{
GIRealInfo *rinfo = (GIRealInfo *)info;
ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
return blob->dipper;
return blob->caller_allocates;
}
/**

View File

@ -551,6 +551,7 @@ GIDirection g_arg_info_get_direction (GIArgInfo *info);
gboolean g_arg_info_is_dipper (GIArgInfo *info);
gboolean g_arg_info_is_return_value (GIArgInfo *info);
gboolean g_arg_info_is_optional (GIArgInfo *info);
gboolean g_arg_info_is_caller_allocates (GIArgInfo *info);
gboolean g_arg_info_may_be_null (GIArgInfo *info);
GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info);
GIScopeType g_arg_info_get_scope (GIArgInfo *info);

View File

@ -1864,7 +1864,7 @@ g_ir_node_build_typelib (GIrNode *node,
blob->name = write_string (node->name, strings, data, offset2);
blob->in = param->in;
blob->out = param->out;
blob->dipper = param->dipper;
blob->caller_allocates = param->caller_allocates;
blob->allow_none = param->allow_none;
blob->optional = param->optional;
blob->transfer_ownership = param->transfer;

View File

@ -153,7 +153,7 @@ struct _GIrNodeParam
gboolean in;
gboolean out;
gboolean dipper;
gboolean caller_allocates;
gboolean optional;
gboolean retval;
gboolean allow_none;

View File

@ -881,8 +881,8 @@ start_parameter (GMarkupParseContext *context,
const gchar *name;
const gchar *direction;
const gchar *retval;
const gchar *dipper;
const gchar *optional;
const gchar *caller_allocates;
const gchar *allow_none;
const gchar *transfer;
const gchar *scope;
@ -897,9 +897,9 @@ start_parameter (GMarkupParseContext *context,
name = find_attribute ("name", attribute_names, attribute_values);
direction = find_attribute ("direction", attribute_names, attribute_values);
retval = find_attribute ("retval", attribute_names, attribute_values);
dipper = find_attribute ("dipper", attribute_names, attribute_values);
optional = find_attribute ("optional", attribute_names, attribute_values);
allow_none = find_attribute ("allow-none", attribute_names, attribute_values);
caller_allocates = find_attribute ("caller-allocates", attribute_names, attribute_values);
transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
scope = find_attribute ("scope", attribute_names, attribute_values);
closure = find_attribute ("closure", attribute_names, attribute_values);
@ -919,16 +919,27 @@ start_parameter (GMarkupParseContext *context,
{
param->in = FALSE;
param->out = TRUE;
if (caller_allocates == NULL)
{
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_INVALID_CONTENT,
"caller-allocates attribute required on out parameters");
return FALSE;
}
param->caller_allocates = strcmp (caller_allocates, "1") == 0;
}
else if (direction && strcmp (direction, "inout") == 0)
{
param->in = TRUE;
param->out = TRUE;
param->caller_allocates = FALSE;
}
else
{
param->in = TRUE;
param->out = FALSE;
param->caller_allocates = FALSE;
}
if (retval && strcmp (retval, "1") == 0)
@ -936,11 +947,6 @@ start_parameter (GMarkupParseContext *context,
else
param->retval = FALSE;
if (dipper && strcmp (dipper, "1") == 0)
param->dipper = TRUE;
else
param->dipper = FALSE;
if (optional && strcmp (optional, "1") == 0)
param->optional = TRUE;
else

View File

@ -349,7 +349,7 @@ typedef union
* add another level of indirection to the parameter type. Ie if
* the type is uint32 in an out parameter, the function actually
* takes an uint32*.
* @dipper: The parameter is a pointer to a struct or object that will
* @caller_allocates: The parameter is a pointer to a struct or object that will
* receive an output of the function.
* @allow_none: Only meaningful for types which are passed as pointers.
* For an in parameter, indicates if it is ok to pass NULL in, for
@ -388,7 +388,7 @@ typedef struct {
guint in : 1;
guint out : 1;
guint dipper : 1;
guint caller_allocates : 1;
guint allow_none : 1;
guint optional : 1;
guint transfer_ownership : 1;
@ -397,7 +397,7 @@ typedef struct {
guint scope : 3;
/* <private> */
guint reserved :21;
/* <public> */
gint8 closure;
gint8 destroy;