summaryrefslogtreecommitdiff
path: root/giscanner
diff options
context:
space:
mode:
authorKrzesimir Nowak <qdlacz@gmail.com>2012-07-04 22:52:02 +0200
committerColin Walters <walters@verbum.org>2012-07-07 17:13:40 -0400
commit3943988d5addbea4603f9b4ee5103c604d03e8f4 (patch)
treee5ca09e5c92ad4b1215d8e37ebaa071064cd60e6 /giscanner
parent09fe4ca9b3e816f87698761f4b66bc2d0c25e4e0 (diff)
downloadgobject-introspection-3943988d5addbea4603f9b4ee5103c604d03e8f4.tar.gz
giscanner: Write detailed information in "type" tag's "c:type" attribute.
That is - write also type qualifiers (const and volatile here). Update existing tests and add a new struct to regress.h having members with type qualifiers. https://bugzilla.gnome.org/show_bug.cgi?id=656445
Diffstat (limited to 'giscanner')
-rw-r--r--giscanner/ast.py4
-rw-r--r--giscanner/girwriter.py4
-rw-r--r--giscanner/transformer.py84
3 files changed, 75 insertions, 17 deletions
diff --git a/giscanner/ast.py b/giscanner/ast.py
index 456f921a..6945d60d 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -45,7 +45,8 @@ from a C type string, or a gtype_name (from g_type_name()).
target_foreign=None,
_target_unknown=False,
is_const=False,
- origin_symbol=None):
+ origin_symbol=None,
+ complete_ctype=None):
self.ctype = ctype
self.gtype_name = gtype_name
self.origin_symbol = origin_symbol
@@ -68,6 +69,7 @@ from a C type string, or a gtype_name (from g_type_name()).
self.target_giname = target_giname
self.target_foreign = target_foreign
self.is_const = is_const
+ self.complete_ctype = complete_ctype
@property
def resolved(self):
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index bfe82a85..cb13d21f 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -272,7 +272,9 @@ and/or use gtk-doc annotations. ''')
def _write_type(self, ntype, relation=None, function=None):
assert isinstance(ntype, ast.Type), ntype
attrs = []
- if ntype.ctype:
+ if ntype.complete_ctype:
+ attrs.append(('c:type', ntype.complete_ctype))
+ elif ntype.ctype:
attrs.append(('c:type', ntype.ctype))
if isinstance(ntype, ast.Varargs):
with self.tagcontext('varargs', []):
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index cf284d8a..91d00afc 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -32,7 +32,7 @@ from .sourcescanner import (
CSYMBOL_TYPE_FUNCTION, CSYMBOL_TYPE_TYPEDEF, CSYMBOL_TYPE_STRUCT,
CSYMBOL_TYPE_ENUM, CSYMBOL_TYPE_UNION, CSYMBOL_TYPE_OBJECT,
CSYMBOL_TYPE_MEMBER, CSYMBOL_TYPE_ELLIPSIS, CSYMBOL_TYPE_CONST,
- TYPE_QUALIFIER_CONST)
+ TYPE_QUALIFIER_CONST, TYPE_QUALIFIER_VOLATILE)
class TransformerException(Exception):
pass
@@ -435,6 +435,45 @@ raise ValueError."""
value = 'gpointer'
return value
+ def _create_complete_source_type(self, source_type):
+ assert source_type is not None
+
+ const = (source_type.type_qualifier & TYPE_QUALIFIER_CONST)
+ volatile = (source_type.type_qualifier & TYPE_QUALIFIER_VOLATILE)
+
+ if source_type.type == CTYPE_VOID:
+ return 'void'
+ elif source_type.type in [CTYPE_BASIC_TYPE,
+ CTYPE_TYPEDEF,
+ CTYPE_STRUCT,
+ CTYPE_UNION,
+ CTYPE_ENUM]:
+ value = source_type.name
+ if const:
+ value = 'const ' + value
+ if volatile:
+ value = 'volatile ' + value
+ elif source_type.type == CTYPE_ARRAY:
+ return self._create_complete_source_type(source_type.base_type)
+ elif source_type.type == CTYPE_POINTER:
+ value = self._create_complete_source_type(source_type.base_type) + '*'
+ # TODO: handle pointer to function as a special case?
+ if const:
+ value += ' const'
+ if volatile:
+ value += ' volatile'
+
+ else:
+ if const:
+ value = 'gconstpointer'
+ else:
+ value = 'gpointer'
+ if volatile:
+ value = 'volatile ' + value
+ return value
+
+ return value
+
def _create_parameters(self, base_type):
# warn if we see annotations for unknown parameters
param_names = set(child.ident for child in base_type.child_list)
@@ -476,6 +515,7 @@ raise ValueError."""
# Special handling for fields; we don't have annotations on them
# to apply later, yet.
if source_type.type == CTYPE_ARRAY:
+ complete_ctype = self._create_complete_source_type(source_type)
# If the array contains anonymous unions, like in the GValue
# struct, we need to handle this specially. This is necessary
# to be able to properly calculate the size of the compound
@@ -484,7 +524,7 @@ raise ValueError."""
if (source_type.base_type.type == CTYPE_UNION and
source_type.base_type.name is None):
synthesized_type = self._synthesize_union_type(symbol, parent_symbol)
- ftype = ast.Array(None, synthesized_type)
+ ftype = ast.Array(None, synthesized_type, complete_ctype=complete_ctype)
else:
ctype = self._create_source_type(source_type)
canonical_ctype = self._canonicalize_ctype(ctype)
@@ -492,8 +532,15 @@ raise ValueError."""
derefed_name = canonical_ctype[:-1]
else:
derefed_name = canonical_ctype
- ftype = ast.Array(None, self.create_type_from_ctype_string(ctype),
- ctype=derefed_name)
+ if complete_ctype[-1] == '*':
+ derefed_complete_ctype = complete_ctype[:-1]
+ else:
+ derefed_complete_ctype = complete_ctype
+ from_ctype = self.create_type_from_ctype_string(ctype,
+ complete_ctype=complete_ctype)
+ ftype = ast.Array(None, from_ctype,
+ ctype=derefed_name,
+ complete_ctype=derefed_complete_ctype)
child_list = list(symbol.base_type.child_list)
ftype.zeroterminated = False
if child_list:
@@ -535,7 +582,9 @@ raise ValueError."""
message.warn(e)
return None
if symbol.base_type.name:
- target = self.create_type_from_ctype_string(symbol.base_type.name)
+ complete_ctype = self._create_complete_source_type(symbol.base_type)
+ target = self.create_type_from_ctype_string(symbol.base_type.name,
+ complete_ctype=complete_ctype)
else:
target = ast.TYPE_ANY
if name in ast.type_names:
@@ -588,20 +637,22 @@ raise ValueError."""
def _create_type_from_base(self, source_type, is_parameter=False, is_return=False):
ctype = self._create_source_type(source_type)
+ complete_ctype = self._create_complete_source_type(source_type)
const = ((source_type.type == CTYPE_POINTER) and
(source_type.base_type.type_qualifier & TYPE_QUALIFIER_CONST))
return self.create_type_from_ctype_string(ctype, is_const=const,
- is_parameter=is_parameter, is_return=is_return)
+ is_parameter=is_parameter, is_return=is_return,
+ complete_ctype=complete_ctype)
def _create_bare_container_type(self, base, ctype=None,
- is_const=False):
+ is_const=False, complete_ctype=None):
if base in ('GList', 'GSList', 'GLib.List', 'GLib.SList'):
if base in ('GList', 'GSList'):
name = 'GLib.' + base[1:]
else:
name = base
return ast.List(name, ast.TYPE_ANY, ctype=ctype,
- is_const=is_const)
+ is_const=is_const, complete_ctype=complete_ctype)
elif base in ('GArray', 'GPtrArray', 'GByteArray',
'GLib.Array', 'GLib.PtrArray', 'GLib.ByteArray',
'GObject.Array', 'GObject.PtrArray', 'GObject.ByteArray'):
@@ -610,13 +661,15 @@ raise ValueError."""
else:
name = 'GLib.' + base[1:]
return ast.Array(name, ast.TYPE_ANY, ctype=ctype,
- is_const=is_const)
+ is_const=is_const, complete_ctype=complete_ctype)
elif base in ('GHashTable', 'GLib.HashTable', 'GObject.HashTable'):
- return ast.Map(ast.TYPE_ANY, ast.TYPE_ANY, ctype=ctype, is_const=is_const)
+ return ast.Map(ast.TYPE_ANY, ast.TYPE_ANY, ctype=ctype, is_const=is_const,
+ complete_ctype=complete_ctype)
return None
def create_type_from_ctype_string(self, ctype, is_const=False,
- is_parameter=False, is_return=False):
+ is_parameter=False, is_return=False,
+ complete_ctype=None):
canonical = self._canonicalize_ctype(ctype)
base = canonical.replace('*', '')
@@ -625,17 +678,18 @@ raise ValueError."""
bare_utf8 = ast.TYPE_STRING.clone()
bare_utf8.ctype = None
return ast.Array(None, bare_utf8, ctype=ctype,
- is_const=is_const)
+ is_const=is_const, complete_ctype=complete_ctype)
fundamental = ast.type_names.get(base)
if fundamental is not None:
return ast.Type(target_fundamental=fundamental.target_fundamental,
ctype=ctype,
- is_const=is_const)
- container = self._create_bare_container_type(base, ctype=ctype, is_const=is_const)
+ is_const=is_const, complete_ctype=complete_ctype)
+ container = self._create_bare_container_type(base, ctype=ctype, is_const=is_const,
+ complete_ctype=complete_ctype)
if container:
return container
- return ast.Type(ctype=ctype, is_const=is_const)
+ return ast.Type(ctype=ctype, is_const=is_const, complete_ctype=complete_ctype)
def _create_parameter(self, symbol):
if symbol.type == CSYMBOL_TYPE_ELLIPSIS: