summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@src.gnome.org>2008-09-29 19:03:37 +0000
committerColin Walters <walters@src.gnome.org>2008-09-29 19:03:37 +0000
commit62d3aea7d2b161710f6b8964cf26baa79b010c5b (patch)
tree3d788e970e8a81fb12f97c06336f6249d49936bb
parent3de4dd3835dd294dc76e186cf0d756356cfe281e (diff)
downloadgobject-introspection-62d3aea7d2b161710f6b8964cf26baa79b010c5b.tar.gz
Write out list and map types, parse 'array' annotation
svn path=/trunk/; revision=634
-rw-r--r--giscanner/ast.py3
-rw-r--r--giscanner/girwriter.py9
-rw-r--r--giscanner/glibtransformer.py12
-rw-r--r--giscanner/scannerlexer.l40
-rw-r--r--giscanner/transformer.py37
-rw-r--r--tests/scanner/annotation-expected.gir73
-rw-r--r--tests/scanner/annotation.c29
-rw-r--r--tests/scanner/annotation.h5
-rw-r--r--tests/scanner/foo-expected.gir2
9 files changed, 136 insertions, 74 deletions
diff --git a/giscanner/ast.py b/giscanner/ast.py
index db1df440..9aee04f4 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -271,7 +271,8 @@ class Return(Node):
def __init__(self, rtype):
Node.__init__(self)
self.type = rtype
- self.transfer = False
+ self.transfer = isinstance(rtype, (List, Map, Array)) or \
+ rtype.name in ('utf8', 'filename')
def __repr__(self):
return 'Return(%r)' % (self.type, )
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 5c9f5bfa..27f9375b 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -23,7 +23,7 @@ from __future__ import with_statement
import os
from .ast import (Callback, Class, Enum, Function, Interface, Member,
- Array, Struct, Alias, Union)
+ Array, Struct, Alias, Union, List, Map)
from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember,
GLibFlags, GLibObject, GLibInterface)
from .xmlwriter import XMLWriter
@@ -143,6 +143,13 @@ class GIRWriter(XMLWriter):
def _type_to_string(self, ntype):
if isinstance(ntype, basestring):
return ntype
+ if isinstance(ntype, List) and ntype.element_type:
+ return '%s<%s>' % (ntype.name,
+ self._type_to_string(ntype.element_type))
+ if isinstance(ntype, Map) and ntype.key_type:
+ return '%s<%s,%s>' % (ntype.name,
+ self._type_to_string(ntype.key_type),
+ self._type_to_string(ntype.value_type))
if isinstance(ntype, Array):
options = []
if not ntype.zeroterminated:
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index bfd8213a..3916b773 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -26,13 +26,15 @@ from ctypes.util import find_library
from . import cgobject
from .ast import (Callback, Enum, Function, Member, Namespace, Parameter,
Property, Return, Struct, Type, Alias, Array,
- Union, type_name_from_ctype)
+ Union, type_name_from_ctype,
+ default_array_types, TYPE_UINT8)
from .transformer import Names
from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
GLibInterface, GLibObject, GLibSignal, GLibBoxedStruct,
GLibBoxedUnion, GLibBoxedOther, type_names)
from .utils import extract_libtool, to_underscores, to_underscores_noprefix
+default_array_types['guchar*'] = TYPE_UINT8
SYMBOL_BLACKLIST = [
# These ones break GError conventions
@@ -61,6 +63,8 @@ class GLibTransformer(object):
def __init__(self, transformer, noclosure=False):
self._transformer = transformer
+ self._transformer.set_container_types(['GList*', 'GSList*'],
+ ['GHashtable*'])
self._namespace_name = None
self._names = Names()
self._uscore_type_names = {}
@@ -167,12 +171,6 @@ class GLibTransformer(object):
no_uscore_prefixed = (prefix + '_' + to_underscores(suffix)).lower()
self._uscore_type_names[no_uscore_prefixed] = node
- def type_is_list(self, ctype):
- return ctype in ['GList*', 'GSList*']
-
- def type_is_map(self, ctype):
- return ctype in ['GHashTable*']
-
# Helper functions
def _type_from_gtype(self, type_id):
diff --git a/giscanner/scannerlexer.l b/giscanner/scannerlexer.l
index 80529f98..4f3a0c13 100644
--- a/giscanner/scannerlexer.l
+++ b/giscanner/scannerlexer.l
@@ -249,34 +249,24 @@ parse_gtkdoc (GISourceScanner *scanner,
if (n_parts == 3)
{
- char *ptr = parts[1];
- GString *current = NULL;
- gint8 pstack = 0;
+ char *ptr = g_strdup (parts[1]);
+ char **option_parts, **option_part;
- current = g_string_new ("");
- value = parts[2];
-
- do
- {
- if (*ptr == '<')
- {
- pstack++;
- if (pstack == 1)
- continue;
- }
- else if (*ptr == '>')
- pstack--;
-
- if (pstack == 0)
+ if (*ptr == '<')
+ {
+ char *end = strchr (ptr, '>');
+ if (end)
{
- options = g_slist_prepend (options, current->str);
- break;
+ *end = '\0';
+ option_parts = g_strsplit (ptr+1, ",", 0);
+ for (option_part = option_parts; *option_part; option_part++)
+ options = g_slist_prepend (options, g_strdup (*option_part));
+ options = g_slist_reverse (options);
+ g_strfreev (option_parts);
}
- g_string_append_c (current, *ptr);
- }
- while (*ptr++);
-
- g_string_free (current, FALSE);
+ }
+ g_free (ptr);
+ value = parts[2];
}
else
value = parts[1];
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index ef394af4..2cdc9209 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -79,6 +79,10 @@ class Transformer(object):
def get_includes(self):
return self._includes
+ def set_container_types(self, list_ctypes, map_ctypes):
+ self._list_ctypes = list_ctypes
+ self._map_ctypes = map_ctypes
+
def set_strip_prefix(self, strip_prefix):
self._strip_prefix = strip_prefix
@@ -306,6 +310,11 @@ class Transformer(object):
"symbol %r of type %s" % (symbol.ident, ctype_name(ctype)))
return node
+ def _parse_and_resolve_ctype(self, ctype):
+ canonical = type_name_from_ctype(ctype)
+ derefed = canonical.replace('*', '')
+ return self.resolve_type_name(derefed)
+
def _create_type(self, source_type, options=[]):
ctype = self._create_source_type(source_type)
if ctype == 'va_list':
@@ -316,7 +325,8 @@ class Transformer(object):
raise SkipError
if ctype in self._list_ctypes:
if len(options) > 0:
- contained_type = options[0]
+ contained_type = self._parse_and_resolve_ctype(options[0])
+ del options[0]
else:
contained_type = None
return List(ctype.replace('*', ''),
@@ -324,21 +334,22 @@ class Transformer(object):
contained_type)
if ctype in self._list_ctypes:
if len(options) > 0:
- key_type = options[0]
- value_type = options[1]
+ key_type = self._parse_and_resolve_ctype(options[0])
+ value_type = self._parse_and_resolve_ctype(options[1])
+ del options[0:2]
else:
key_type = None
value_type = None
return Map(ctype.replace('*', ''),
ctype,
key_type, value_type)
- if ctype in default_array_types:
+ if (ctype in default_array_types) or ('array' in options):
+ if 'array' in options:
+ options.remove('array')
derefed = ctype[:-1] # strip the *
return Array(None, ctype,
type_name_from_ctype(derefed))
- type_name = type_name_from_ctype(ctype)
- type_name = type_name.replace('*', '')
- resolved_type_name = self.resolve_type_name(type_name)
+ resolved_type_name = self._parse_and_resolve_ctype(ctype)
return Type(resolved_type_name, ctype)
def _create_parameter(self, symbol, options):
@@ -353,6 +364,8 @@ class Transformer(object):
param.direction = 'out'
elif option == 'transfer':
param.transfer = True
+ elif option == 'notransfer':
+ param.transfer = False
elif option == 'allow-none':
param.allow_none = True
else:
@@ -360,17 +373,15 @@ class Transformer(object):
option, )
return param
- def _create_return(self, source_type, options=None):
- if not options:
- options = []
- rtype = self._create_type(source_type)
+ def _create_return(self, source_type, options=[]):
+ rtype = self._create_type(source_type, options)
rtype = self.resolve_param_type(rtype)
return_ = Return(rtype)
for option in options:
- if option == 'caller-owns':
+ if option == 'transfer':
return_.transfer = True
else:
- print 'Unhandled parameter annotation option: %s' % (
+ print 'Unhandled parameter annotation option: %r' % (
option, )
return return_
diff --git a/tests/scanner/annotation-expected.gir b/tests/scanner/annotation-expected.gir
index b15b5fda..10b6b654 100644
--- a/tests/scanner/annotation-expected.gir
+++ b/tests/scanner/annotation-expected.gir
@@ -60,7 +60,7 @@
<parameter name="object">
<type name="Object" c:type="AnnotationObject*"/>
</parameter>
- <parameter name="allow_none" allow-none="1">
+ <parameter name="somearg" allow-none="1">
<type name="utf8" c:type="gchar*"/>
</parameter>
</parameters>
@@ -86,7 +86,7 @@
<parameter name="object">
<type name="Object" c:type="AnnotationObject*"/>
</parameter>
- <parameter name="inoutarg">
+ <parameter name="inoutarg" direction="inout">
<type name="int" c:type="int*"/>
</parameter>
</parameters>
@@ -99,7 +99,7 @@
<parameter name="object">
<type name="Object" c:type="AnnotationObject*"/>
</parameter>
- <parameter name="inoutarg" direction="inout">
+ <parameter name="inoutarg" direction="inout" allow-none="1">
<type name="int" c:type="int*"/>
</parameter>
</parameters>
@@ -126,8 +126,8 @@
<parameter name="object">
<type name="Object" c:type="AnnotationObject*"/>
</parameter>
- <parameter name="toown" transfer-ownership="1">
- <type name="GObject.Object" c:type="GObject*"/>
+ <parameter name="toown" direction="out" transfer-ownership="1">
+ <type name="GObject.Object" c:type="GObject**"/>
</parameter>
</parameters>
</function>
@@ -140,20 +140,18 @@
<parameter name="object">
<type name="Object" c:type="AnnotationObject*"/>
</parameter>
- <parameter name="toown1" transfer-ownership="1">
- <type name="GObject.Object" c:type="GObject*"/>
+ <parameter name="toown1" direction="out" transfer-ownership="1">
+ <type name="GObject.Object" c:type="GObject**"/>
</parameter>
- <parameter name="toown2" transfer-ownership="1">
- <type name="GObject.Object" c:type="GObject*"/>
+ <parameter name="toown2" direction="out" transfer-ownership="1">
+ <type name="GObject.Object" c:type="GObject**"/>
</parameter>
</parameters>
</function>
<function name="object_get_strings"
c:identifier="annotation_object_get_strings">
- <return-value>
- <type name="GLib.List" transfer-ownership="1">
- <type name="utf8" relation="element"/>
- </type>
+ <return-value transfer-ownership="1">
+ <type name="GLib.List&lt;utf8&gt;" c:type="GList*"/>
</return-value>
<parameters>
<parameter name="object">
@@ -163,15 +161,58 @@
</function>
<function name="object_get_objects"
c:identifier="annotation_object_get_objects">
+ <return-value transfer-ownership="1">
+ <type name="GLib.SList&lt;Object&gt;" c:type="GSList*"/>
+ </return-value>
+ <parameters>
+ <parameter name="object">
+ <type name="Object" c:type="AnnotationObject*"/>
+ </parameter>
+ </parameters>
+ </function>
+ <function name="object_use_buffer"
+ c:identifier="annotation_object_use_buffer">
+ <return-value>
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="object">
+ <type name="Object" c:type="AnnotationObject*"/>
+ </parameter>
+ <parameter name="bytes">
+ <type name="uint8[]" c:type="guchar*"/>
+ </parameter>
+ </parameters>
+ </function>
+ <function name="object_compute_sum"
+ c:identifier="annotation_object_compute_sum">
+ <return-value>
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="object">
+ <type name="Object" c:type="AnnotationObject*"/>
+ </parameter>
+ <parameter name="nums">
+ <type name="int[]" c:type="int*"/>
+ </parameter>
+ </parameters>
+ </function>
+ <function name="object_compute_sum_n"
+ c:identifier="annotation_object_compute_sum_n">
<return-value>
- <type name="GLib.SList" transfer-ownership="1">
- <type name="Object" relation="element"/>
- </type>
+ <type name="none" c:type="void"/>
</return-value>
<parameters>
<parameter name="object">
<type name="Object" c:type="AnnotationObject*"/>
</parameter>
+ <parameter name="nums">
+ <type name="int[]" c:type="int*"/>
+ </parameter>
+ <parameter name="n_nums">
+ <type name="int" c:type="int"/>
+ </parameter>
</parameters>
</function>
<function name="object_do_not_use"
diff --git a/tests/scanner/annotation.c b/tests/scanner/annotation.c
index 801756a9..fc0dbd48 100644
--- a/tests/scanner/annotation.c
+++ b/tests/scanner/annotation.c
@@ -23,7 +23,7 @@ annotation_object_init (AnnotationObject *object)
gint
annotation_object_method (AnnotationObject *object)
{
- return 1;
+ return 1;
}
/**
@@ -38,7 +38,8 @@ annotation_object_method (AnnotationObject *object)
gint
annotation_object_in (AnnotationObject *object, int *outarg)
{
- return 1;
+ *outarg = 2;
+ return 1;
}
/**
@@ -53,7 +54,8 @@ annotation_object_in (AnnotationObject *object, int *outarg)
gint
annotation_object_out (AnnotationObject *object, int *outarg)
{
- return 1;
+ *outarg = 2;
+ return 1;
}
@@ -63,13 +65,13 @@ annotation_object_out (AnnotationObject *object, int *outarg)
*
* This is a test for out arguments
*
- * @inoutarg: <out>: This is an argument test
+ * @inoutarg: <inout>: This is an argument test
* Return value: an int
*/
gint
annotation_object_inout (AnnotationObject *object, int *inoutarg)
{
- return 1;
+ return *inoutarg += 1;
}
/**
@@ -84,7 +86,7 @@ annotation_object_inout (AnnotationObject *object, int *inoutarg)
gint
annotation_object_inout2 (AnnotationObject *object, int *inoutarg)
{
- return 1;
+ return *inoutarg += 1;
}
@@ -100,7 +102,9 @@ annotation_object_inout2 (AnnotationObject *object, int *inoutarg)
gint
annotation_object_inout3 (AnnotationObject *object, int *inoutarg)
{
- return 1;
+ if (inoutarg)
+ return *inoutarg + 1;
+ return 1;
}
/**
@@ -115,7 +119,7 @@ annotation_object_inout3 (AnnotationObject *object, int *inoutarg)
gint
annotation_object_calleeowns (AnnotationObject *object, GObject **toown)
{
- return 1;
+ return 1;
}
@@ -134,7 +138,7 @@ annotation_object_calleesowns (AnnotationObject *object,
GObject **toown1,
GObject **toown2)
{
- return 1;
+ return 1;
}
@@ -199,6 +203,13 @@ annotation_object_create_object (AnnotationObject *object)
return g_object_ref (object);
}
+void
+annotation_object_use_buffer (AnnotationObject *object,
+ guchar *bytes)
+{
+
+}
+
/**
* annotation_object_compute_sum:
* @object: a #GObject
diff --git a/tests/scanner/annotation.h b/tests/scanner/annotation.h
index 124237fa..0e660015 100644
--- a/tests/scanner/annotation.h
+++ b/tests/scanner/annotation.h
@@ -21,7 +21,7 @@ gint annotation_object_out (AnnotationObject *object,
int *outarg);
GObject* annotation_object_create_object(AnnotationObject *object);
GObject* annotation_object_allow_none (AnnotationObject *object,
- gchar *allow_none);
+ gchar *somearg);
gint annotation_object_inout (AnnotationObject *object,
int *inoutarg);
gint annotation_object_inout2 (AnnotationObject *object,
@@ -38,6 +38,9 @@ gint annotation_object_calleesowns (AnnotationObject *object,
GList* annotation_object_get_strings (AnnotationObject *object);
GSList* annotation_object_get_objects (AnnotationObject *object);
+void annotation_object_use_buffer (AnnotationObject *object,
+ guchar *bytes);
+
void annotation_object_compute_sum (AnnotationObject *object,
int *nums);
diff --git a/tests/scanner/foo-expected.gir b/tests/scanner/foo-expected.gir
index cb771e78..057c3a70 100644
--- a/tests/scanner/foo-expected.gir
+++ b/tests/scanner/foo-expected.gir
@@ -133,7 +133,7 @@
</parameters>
</callback>
<glib:signal name="signal">
- <return-value>
+ <return-value transfer-ownership="1">
<type name="utf8" c:type="gchararray"/>
</return-value>
<parameters>