summaryrefslogtreecommitdiff
path: root/giscanner
diff options
context:
space:
mode:
Diffstat (limited to 'giscanner')
-rw-r--r--giscanner/annotationparser.py63
-rw-r--r--giscanner/ast.py12
-rw-r--r--giscanner/girparser.py6
-rw-r--r--giscanner/girwriter.py8
-rw-r--r--giscanner/maintransformer.py9
5 files changed, 93 insertions, 5 deletions
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index 3952b24b..e567115a 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -193,11 +193,13 @@ ANN_ARRAY = 'array'
ANN_ATTRIBUTES = 'attributes'
ANN_CLOSURE = 'closure'
ANN_CONSTRUCTOR = 'constructor'
+ANN_COPY_FUNC = 'copy-func'
ANN_DEFAULT_VALUE = 'default-value'
ANN_DESTROY = 'destroy'
ANN_ELEMENT_TYPE = 'element-type'
ANN_EMITTER = 'emitter'
ANN_FOREIGN = 'foreign'
+ANN_FREE_FUNC = 'free-func'
ANN_GET_PROPERTY = 'get-property'
ANN_GET_VALUE_FUNC = 'get-value-func'
ANN_GETTER = 'getter'
@@ -790,6 +792,18 @@ class GtkDocAnnotatable(object):
self._validate_annotation(position, ann_name, options, exact_n_options=0)
+ def _do_validate_copy_func(self, position, ann_name, options):
+ '''
+ Validate the ``(copy-func)`` annotation.
+
+ :param position: :class:`giscanner.message.Position` of the line in the source file
+ containing the annotation to be validated
+ :param ann_name: name of the annotation holding the options to validate
+ :param options: annotation options to validate
+ '''
+
+ self._validate_annotation(position, ann_name, options, exact_n_options=1)
+
def _do_validate_default_value(self, position, ann_name, options):
'''
Validate the ``(default-value)`` annotation.
@@ -851,6 +865,18 @@ class GtkDocAnnotatable(object):
self._validate_annotation(position, ann_name, options, exact_n_options=0)
+ def _do_validate_free_func(self, position, ann_name, options):
+ '''
+ Validate the ``(free-func)`` annotation.
+
+ :param position: :class:`giscanner.message.Position` of the line in the source file
+ containing the annotation to be validated
+ :param ann_name: name of the annotation holding the options to validate
+ :param options: annotation options to validate
+ '''
+
+ self._validate_annotation(position, ann_name, options, exact_n_options=1)
+
def _do_validate_get_property(self, position, ann_name, options):
'''
Validate the ``(get-property)`` annotation.
@@ -1127,9 +1153,24 @@ class GtkDocParameter(GtkDocAnnotatable):
__slots__ = ('name', 'description')
- valid_annotations = (ANN_ALLOW_NONE, ANN_ARRAY, ANN_ATTRIBUTES, ANN_CLOSURE, ANN_DESTROY,
- ANN_ELEMENT_TYPE, ANN_IN, ANN_INOUT, ANN_OUT, ANN_SCOPE, ANN_SKIP,
- ANN_TRANSFER, ANN_TYPE, ANN_OPTIONAL, ANN_NULLABLE, ANN_NOT)
+ valid_annotations = (
+ ANN_ALLOW_NONE,
+ ANN_ARRAY,
+ ANN_ATTRIBUTES,
+ ANN_CLOSURE,
+ ANN_DESTROY,
+ ANN_ELEMENT_TYPE,
+ ANN_IN,
+ ANN_INOUT,
+ ANN_OUT,
+ ANN_SCOPE,
+ ANN_SKIP,
+ ANN_TRANSFER,
+ ANN_TYPE,
+ ANN_OPTIONAL,
+ ANN_NULLABLE,
+ ANN_NOT,
+ )
def __init__(self, name, position=None):
GtkDocAnnotatable.__init__(self, position)
@@ -1151,8 +1192,18 @@ class GtkDocTag(GtkDocAnnotatable):
__slots__ = ('name', 'value', 'description')
- valid_annotations = (ANN_ALLOW_NONE, ANN_ARRAY, ANN_ATTRIBUTES, ANN_ELEMENT_TYPE, ANN_SKIP,
- ANN_TRANSFER, ANN_TYPE, ANN_NULLABLE, ANN_OPTIONAL, ANN_NOT)
+ valid_annotations = (
+ ANN_ALLOW_NONE,
+ ANN_ARRAY,
+ ANN_ATTRIBUTES,
+ ANN_ELEMENT_TYPE,
+ ANN_SKIP,
+ ANN_TRANSFER,
+ ANN_TYPE,
+ ANN_NULLABLE,
+ ANN_OPTIONAL,
+ ANN_NOT,
+ )
def __init__(self, name, position=None):
GtkDocAnnotatable.__init__(self, position)
@@ -1182,9 +1233,11 @@ class GtkDocCommentBlock(GtkDocAnnotatable):
valid_annotations = (
ANN_ATTRIBUTES,
ANN_CONSTRUCTOR,
+ ANN_COPY_FUNC,
ANN_DEFAULT_VALUE,
ANN_EMITTER,
ANN_FOREIGN,
+ ANN_FREE_FUNC,
ANN_GET_PROPERTY,
ANN_GET_VALUE_FUNC,
ANN_GETTER,
diff --git a/giscanner/ast.py b/giscanner/ast.py
index dac326cb..bbfbe267 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -1127,6 +1127,12 @@ class Record(Compound):
# If non-None, this record defines the FooClass C structure
# for some Foo GObject (or similar for GInterface)
self.is_gtype_struct_for = None
+ # If non-None, this record has a copy function for heap
+ # allocated instances
+ self.copy_func = None
+ # If non-None, this record has a free function for heap
+ # allocated instances
+ self.free_func = None
class Union(Compound):
@@ -1145,6 +1151,12 @@ class Union(Compound):
c_symbol_prefix=c_symbol_prefix,
disguised=disguised,
tag_name=tag_name)
+ # If non-None, this union has a copy function for heap
+ # allocated instances
+ self.copy_func = None
+ # If non-None, this union has a free function for heap
+ # allocated instances
+ self.free_func = None
class Boxed(Node, Registered):
diff --git a/giscanner/girparser.py b/giscanner/girparser.py
index 5fc22899..2f8c5f66 100644
--- a/giscanner/girparser.py
+++ b/giscanner/girparser.py
@@ -462,14 +462,20 @@ class GIRParser(object):
def _parse_record(self, node, anonymous=False):
struct = self._parse_compound(ast.Record, node)
is_gtype_struct_for = node.attrib.get(_glibns('is-gtype-struct-for'))
+ copy_func = node.attrib.get('copy-function')
+ free_func = node.attrib.get('free-function')
if is_gtype_struct_for is not None:
struct.is_gtype_struct_for = self._namespace.type_from_name(is_gtype_struct_for)
+ struct.copy_func = copy_func
+ struct.free_func = free_func
if not anonymous:
self._namespace.append(struct)
return struct
def _parse_union(self, node, anonymous=False):
union = self._parse_compound(ast.Union, node)
+ union.copy_func = node.attrib.get('copy-function')
+ union.free_func = node.attrib.get('free-function')
if not anonymous:
self._namespace.append(union)
return union
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index a3b3bc3e..810acad6 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -593,6 +593,10 @@ class GIRWriter(XMLWriter):
is_gtype_struct = True
attrs.append(('glib:is-gtype-struct-for',
self._type_to_name(record.is_gtype_struct_for)))
+ if record.copy_func:
+ attrs.append(('copy-function', record.copy_func))
+ if record.free_func:
+ attrs.append(('free-function', record.free_func))
self._append_version(record, attrs)
self._append_node_generic(record, attrs)
self._append_registered(record, attrs)
@@ -621,6 +625,10 @@ class GIRWriter(XMLWriter):
self._append_registered(union, attrs)
if union.c_symbol_prefix:
attrs.append(('c:symbol-prefix', union.c_symbol_prefix))
+ if union.copy_func:
+ attrs.append(('copy-function', union.copy_func))
+ if union.free_func:
+ attrs.append(('free-function', union.free_func))
with self.tagcontext('union', attrs):
self._write_generic(union)
if union.fields:
diff --git a/giscanner/maintransformer.py b/giscanner/maintransformer.py
index 285712c7..4393e160 100644
--- a/giscanner/maintransformer.py
+++ b/giscanner/maintransformer.py
@@ -28,11 +28,13 @@ from .annotationparser import (
ANN_ATTRIBUTES,
ANN_CLOSURE,
ANN_CONSTRUCTOR,
+ ANN_COPY_FUNC,
ANN_DEFAULT_VALUE,
ANN_DESTROY,
ANN_ELEMENT_TYPE,
ANN_EMITTER,
ANN_FOREIGN,
+ ANN_FREE_FUNC,
ANN_GET_PROPERTY,
ANN_GET_VALUE_FUNC,
ANN_GETTER,
@@ -310,6 +312,13 @@ class MainTransformer(object):
node.get_value_func = annotation[0] if annotation else None
if isinstance(node, ast.Constant):
self._apply_annotations_constant(node)
+ if isinstance(node, (ast.Record, ast.Union)):
+ block = self._get_block(node)
+ if block:
+ annotation = block.annotations.get(ANN_COPY_FUNC)
+ node.copy_func = annotation[0] if annotation else None
+ annotation = block.annotations.get(ANN_FREE_FUNC)
+ node.free_func = annotation[0] if annotation else None
return True
def _adjust_container_type(self, parent, node, annotations):