diff options
author | Colin Walters <walters@verbum.org> | 2009-12-16 11:47:19 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2010-05-26 13:00:56 -0400 |
commit | 5589687a1fa5d4c7f15213ee3cd6860a03587ced (patch) | |
tree | fcd147f09b04edd06af55ea8c28c6b7320e8e7b5 /giscanner | |
parent | 786da5cdd2dfc775c08d127c5e855eb091d24974 (diff) | |
download | gobject-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.py | 24 | ||||
-rw-r--r-- | giscanner/ast.py | 1 | ||||
-rw-r--r-- | giscanner/girwriter.py | 2 |
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: |