summaryrefslogtreecommitdiff
path: root/giscanner
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2009-12-16 11:47:19 -0500
committerColin Walters <walters@verbum.org>2010-05-26 13:00:56 -0400
commit5589687a1fa5d4c7f15213ee3cd6860a03587ced (patch)
treefcd147f09b04edd06af55ea8c28c6b7320e8e7b5 /giscanner
parent786da5cdd2dfc775c08d127c5e855eb091d24974 (diff)
downloadgobject-introspection-5589687a1fa5d4c7f15213ee3cd6860a03587ced.tar.gz
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
Diffstat (limited to 'giscanner')
-rw-r--r--giscanner/annotationparser.py24
-rw-r--r--giscanner/ast.py1
-rw-r--r--giscanner/girwriter.py2
3 files changed, 25 insertions, 2 deletions
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index 93e4184c..1fd82cc3 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -587,13 +587,15 @@ class AnnotationApplier(object):
def _parse_param_ret_common(self, parent, node, tag):
options = getattr(tag, 'options', {})
- node.direction = self._extract_direction(node, options)
+ (node.direction, node.caller_allocates) = \
+ self._extract_direction(node, options)
container_type = self._extract_container_type(
parent, node, options)
if container_type is not None:
node.type = container_type
if node.direction is None:
node.direction = self._guess_direction(node)
+ node.caller_allocates = False
node.transfer = self._extract_transfer(parent, node, options)
param_type = options.get(OPT_TYPE)
if param_type:
@@ -608,16 +610,32 @@ class AnnotationApplier(object):
node.doc = tag.comment
def _extract_direction(self, node, options):
+ caller_allocates = False
if (OPT_INOUT in options or
OPT_INOUT_ALT in options):
direction = PARAM_DIRECTION_INOUT
elif OPT_OUT in options:
+ subtype = options[OPT_OUT]
+ if subtype is not None:
+ subtype = subtype.one()
direction = PARAM_DIRECTION_OUT
+ if subtype in (None, ''):
+ if (node.type.name not in BASIC_GIR_TYPES) and node.type.ctype:
+ caller_allocates = '**' not in node.type.ctype
+ else:
+ caller_allocates = False
+ elif subtype == 'caller-allocates':
+ caller_allocates = True
+ elif subtype == 'callee-allocates':
+ caller_allocates = False
+ else:
+ raise InvalidAnnotationError(
+ "out direction for %s is invalid (%r)" % (node, subtype))
elif OPT_IN in options:
direction = PARAM_DIRECTION_IN
else:
direction = node.direction
- return direction
+ return (direction, caller_allocates)
def _guess_array(self, node):
ctype = node.type.ctype
@@ -885,6 +903,8 @@ class AnnotationApplier(object):
elif isinstance(node, Parameter):
if node.direction in [PARAM_DIRECTION_INOUT,
PARAM_DIRECTION_OUT]:
+ if node.caller_allocates:
+ return PARAM_TRANSFER_NONE
return PARAM_TRANSFER_FULL
# This one is a hack for compatibility; the transfer
# for string parameters really has no defined meaning.
diff --git a/giscanner/ast.py b/giscanner/ast.py
index bd162514..902a3f6f 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -367,6 +367,7 @@ class Parameter(TypeContainer):
else:
self.direction = PARAM_DIRECTION_IN
+ self.caller_allocates = False
self.allow_none = allow_none
self.scope = scope
self.closure_index = -1
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index e1a1f020..48791b11 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -207,6 +207,8 @@ and/or use gtk-doc annotations. ''')
attrs.append(('name', parameter.name))
if parameter.direction != 'in':
attrs.append(('direction', parameter.direction))
+ attrs.append(('caller-allocates',
+ '1' if parameter.caller_allocates else '0'))
attrs.append(('transfer-ownership',
parameter.transfer))
if parameter.allow_none: