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
self.target_giname = target_giname
self.target_foreign = target_foreign
self.is_const = is_const
+ self.complete_ctype = complete_ctype
@property
def resolved(self):
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', []):
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
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)
# 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
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)
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:
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:
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'):
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('*', '')
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:
<doc xml:whitespace="preserve">This is a callback.</doc>
<return-value transfer-ownership="none">
<doc xml:whitespace="preserve">array of ints</doc>
- <type name="gint" c:type="gint*"/>
+ <type name="gint" c:type="const gint*"/>
</return-value>
<parameters>
<parameter name="in" transfer-ownership="none">
<doc xml:whitespace="preserve">array of ints</doc>
- <type name="gint" c:type="gint*"/>
+ <type name="gint" c:type="const gint*"/>
</parameter>
</parameters>
</callback>
<type name="Object" c:type="AnnotationObject*"/>
</parameter>
<parameter name="item" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
<parameter name="user_data" transfer-ownership="none" closure="2">
<type name="gpointer" c:type="gpointer"/>
</return-value>
<parameters>
<parameter name="somearg" transfer-ownership="none" allow-none="1">
- <type name="utf8" c:type="gchar*"/>
+ <type name="utf8" c:type="const gchar*"/>
</parameter>
</parameters>
</method>
<attribute name="some.annotation" value="value"/>
<attribute name="another.annotation" value="blahvalue"/>
<doc xml:whitespace="preserve">Some data.</doc>
- <type name="utf8" c:type="gchar*"/>
+ <type name="utf8" c:type="const gchar*"/>
</parameter>
</parameters>
</function>
</method>
<method name="get_name" c:identifier="foo_object_get_name">
<return-value transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</return-value>
</method>
<method name="handle_glyph" c:identifier="foo_object_handle_glyph">
</return-value>
<parameters>
<parameter name="target" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
</parameters>
</method>
<parameters>
<parameter name="r2" transfer-ownership="none">
<doc xml:whitespace="preserve">source rectangle</doc>
- <type name="Rectangle" c:type="FooRectangle*"/>
+ <type name="Rectangle" c:type="const FooRectangle*"/>
</parameter>
</parameters>
</method>
<type name="gint" c:type="int"/>
</field>
<field name="lines" writable="1">
- <array zero-terminated="0" c:type="gchar" fixed-size="80">
+ <array zero-terminated="0" c:type="char" fixed-size="80">
<type name="gchar" c:type="char"/>
</array>
</field>
</return-value>
<parameters>
<parameter name="param" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
<parameter transfer-ownership="none">
<varargs>
</return-value>
<parameters>
<parameter name="param" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
</parameters>
</function>
<function name="test_const_char_retval"
c:identifier="foo_test_const_char_retval">
<return-value transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</return-value>
</function>
<function name="test_const_struct_param"
</return-value>
<parameters>
<parameter name="param" transfer-ownership="none">
- <type name="Struct" c:type="FooStruct*"/>
+ <type name="Struct" c:type="const FooStruct*"/>
</parameter>
</parameters>
</function>
<function name="test_const_struct_retval"
c:identifier="foo_test_const_struct_retval">
<return-value transfer-ownership="none">
- <type name="Struct" c:type="FooStruct*"/>
+ <type name="Struct" c:type="const FooStruct*"/>
</return-value>
</function>
<function name="test_string_array" c:identifier="foo_test_string_array">
</return-value>
<parameters>
<parameter name="error" transfer-ownership="none">
- <type name="GLib.Error" c:type="GError*"/>
+ <type name="GLib.Error" c:type="const GError*"/>
</parameter>
</parameters>
</callback>
glib:nick="value4"/>
<function name="param" c:identifier="regress_test_enum_param">
<return-value transfer-ownership="none">
- <type name="utf8" c:type="gchar*"/>
+ <type name="utf8" c:type="const gchar*"/>
</return-value>
<parameters>
<parameter name="e" transfer-ownership="none">
<parameters>
<parameter name="obj" transfer-ownership="none">
<type name="TestFundamentalObject"
- c:type="RegressTestFundamentalObject*"/>
+ c:type="const RegressTestFundamentalObject*"/>
</parameter>
</parameters>
</callback>
</return-value>
<parameters>
<parameter name="data" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
</parameters>
</constructor>
</return-value>
<parameters>
<parameter name="x" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
</parameters>
</constructor>
<parameters>
<parameter name="somestr" transfer-ownership="none">
<doc xml:whitespace="preserve">Meaningless string</doc>
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
</parameters>
</virtual-method>
<parameters>
<parameter name="somestr" transfer-ownership="none">
<doc xml:whitespace="preserve">Meaningless string</doc>
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
</parameters>
</method>
<type name="gint" c:type="int*"/>
</parameter>
<parameter name="foo" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
<parameter name="q"
direction="out"
<type name="gint" c:type="int*"/>
</parameter>
<parameter name="foo" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
<parameter name="q"
direction="out"
</parameter>
<parameter name="somestr" transfer-ownership="none">
<doc xml:whitespace="preserve">Meaningless string</doc>
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
</parameters>
</callback>
<function name="const_return"
c:identifier="regress_test_simple_boxed_a_const_return">
<return-value transfer-ownership="none">
- <type name="TestSimpleBoxedA" c:type="RegressTestSimpleBoxedA*"/>
+ <type name="TestSimpleBoxedA"
+ c:type="const RegressTestSimpleBoxedA*"/>
</return-value>
</function>
</record>
<type name="gpointer" c:type="gpointer"/>
</field>
</union>
+ <record name="TestStructF" c:type="RegressTestStructF">
+ <field name="ref_count" writable="1">
+ <type name="gint" c:type="volatile gint"/>
+ </field>
+ <field name="data1" writable="1">
+ <type name="gint" c:type="const gint*"/>
+ </field>
+ <field name="data2" writable="1">
+ <type name="gint" c:type="const gint* const"/>
+ </field>
+ <field name="data3" writable="1">
+ <type name="gint" c:type="const gint* const* const"/>
+ </field>
+ <field name="data4" writable="1">
+ <type name="gint" c:type="const gint** const*"/>
+ </field>
+ <field name="data5" writable="1">
+ <type name="gint" c:type="volatile gint* const"/>
+ </field>
+ <field name="data6" writable="1">
+ <type name="gint" c:type="const gint* volatile"/>
+ </field>
+ </record>
<record name="TestStructFixedArray" c:type="RegressTestStructFixedArray">
<field name="just_int" writable="1">
<type name="gint" c:type="gint"/>
c:identifier="regress_test_enum_param"
moved-to="TestEnum.param">
<return-value transfer-ownership="none">
- <type name="utf8" c:type="gchar*"/>
+ <type name="utf8" c:type="const gchar*"/>
</return-value>
<parameters>
<parameter name="e" transfer-ownership="none">
</return-value>
<parameters>
<parameter name="in" transfer-ownership="none">
- <type name="GLib.HashTable" c:type="GHashTable*">
+ <type name="GLib.HashTable" c:type="const GHashTable*">
<type name="utf8"/>
<type name="utf8"/>
</type>
<function name="test_ghash_nothing_return"
c:identifier="regress_test_ghash_nothing_return">
<return-value transfer-ownership="none">
- <type name="GLib.HashTable" c:type="GHashTable*">
+ <type name="GLib.HashTable" c:type="const GHashTable*">
<type name="utf8"/>
<type name="utf8"/>
</type>
</return-value>
<parameters>
<parameter name="in" transfer-ownership="none" allow-none="1">
- <type name="GLib.HashTable" c:type="GHashTable*">
+ <type name="GLib.HashTable" c:type="const GHashTable*">
<type name="utf8"/>
<type name="utf8"/>
</type>
caller-allocates="0"
transfer-ownership="full"
allow-none="1">
- <type name="GLib.HashTable" c:type="GHashTable**">
+ <type name="GLib.HashTable" c:type="const GHashTable**">
<type name="utf8"/>
<type name="utf8"/>
</type>
<function name="test_ghash_null_return"
c:identifier="regress_test_ghash_null_return">
<return-value transfer-ownership="none">
- <type name="GLib.HashTable" c:type="GHashTable*">
+ <type name="GLib.HashTable" c:type="const GHashTable*">
<type name="utf8"/>
<type name="utf8"/>
</type>
</return-value>
<parameters>
<parameter name="in" transfer-ownership="none">
- <type name="GLib.List" c:type="GList*">
+ <type name="GLib.List" c:type="const GList*">
<type name="utf8"/>
</type>
</parameter>
<function name="test_glist_nothing_return"
c:identifier="regress_test_glist_nothing_return">
<return-value transfer-ownership="none">
- <type name="GLib.List" c:type="GList*">
+ <type name="GLib.List" c:type="const GList*">
<type name="utf8"/>
</type>
</return-value>
</return-value>
<parameters>
<parameter name="in" transfer-ownership="none">
- <type name="GLib.SList" c:type="GSList*">
+ <type name="GLib.SList" c:type="const GSList*">
<type name="utf8"/>
</type>
</parameter>
<function name="test_gslist_nothing_return"
c:identifier="regress_test_gslist_nothing_return">
<return-value transfer-ownership="none">
- <type name="GLib.SList" c:type="GSList*">
+ <type name="GLib.SList" c:type="const GSList*">
<type name="utf8"/>
</type>
</return-value>
<type name="gint" c:type="int*"/>
</parameter>
<parameter name="in" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
</parameters>
</function>
</return-value>
<parameters>
<parameter name="v" transfer-ownership="none">
- <type name="GObject.Value" c:type="GValue*"/>
+ <type name="GObject.Value" c:type="const GValue*"/>
</parameter>
</parameters>
</function>
c:identifier="regress_test_simple_boxed_a_const_return"
moved-to="TestSimpleBoxedA.const_return">
<return-value transfer-ownership="none">
- <type name="TestSimpleBoxedA" c:type="RegressTestSimpleBoxedA*"/>
+ <type name="TestSimpleBoxedA" c:type="const RegressTestSimpleBoxedA*"/>
</return-value>
</function>
<function name="test_simple_callback"
</function>
<function name="test_strv_out_c" c:identifier="regress_test_strv_out_c">
<return-value transfer-ownership="none">
- <array c:type="char**">
+ <array c:type="const char* const*">
<type name="utf8"/>
</array>
</return-value>
<type name="gint" c:type="int*"/>
</parameter>
<parameter name="foo" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
<parameter name="q"
direction="out"
<type name="gint" c:type="int*"/>
</parameter>
<parameter name="foo" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
<parameter name="q"
direction="out"
<type name="gint" c:type="int*"/>
</parameter>
<parameter name="foo" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
<parameter name="q"
direction="out"
<function name="test_unsigned_enum_param"
c:identifier="regress_test_unsigned_enum_param">
<return-value transfer-ownership="none">
- <type name="utf8" c:type="gchar*"/>
+ <type name="utf8" c:type="const gchar*"/>
</return-value>
<parameters>
<parameter name="e" transfer-ownership="none">
</return-value>
<parameters>
<parameter name="in" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
</parameters>
</function>
c:identifier="regress_test_utf8_const_return">
<return-value transfer-ownership="none">
<doc xml:whitespace="preserve">UTF-8 string</doc>
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</return-value>
</function>
<function name="test_utf8_inout" c:identifier="regress_test_utf8_inout">
</return-value>
<parameters>
<parameter name="value" transfer-ownership="none">
- <type name="GObject.Value" c:type="GValue*"/>
+ <type name="GObject.Value" c:type="const GValue*"/>
</parameter>
</parameters>
</function>
c:identifier="regress_test_value_return">
<return-value transfer-ownership="none">
<doc xml:whitespace="preserve">the int wrapped in a GValue.</doc>
- <type name="GObject.Value" c:type="GValue*"/>
+ <type name="GObject.Value" c:type="const GValue*"/>
</return-value>
<parameters>
<parameter name="i" transfer-ownership="none">
</return-value>
<parameters>
<parameter name="path" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
<parameter name="user_data" transfer-ownership="none" closure="1">
<type name="gpointer" c:type="gpointer"/>
</return-value>
<parameters>
<parameter name="path" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
<parameter name="func"
transfer-ownership="none"
</return-value>
<parameters>
<parameter name="path" transfer-ownership="none">
- <type name="utf8" c:type="char*"/>
+ <type name="utf8" c:type="const char*"/>
</parameter>
<parameter name="func"
transfer-ownership="none"
typedef struct _RegressTestStructB RegressTestStructB;
typedef struct _RegressTestStructC RegressTestStructC;
typedef struct _RegressTestStructD RegressTestStructD;
+typedef struct _RegressTestStructF RegressTestStructF;
struct _RegressTestStructA
{
* @field: (type RegressTestObj):
* @list: (element-type RegressTestObj):
* @garray: (element-type RegressTestObj):
+ * @ref_count:
*/
struct _RegressTestStructD
{
} some_union[2];
};
+/* This one has members with const or volatile modifiers. */
+struct _RegressTestStructF
+{
+ volatile gint ref_count;
+ const gint *data1;
+ const gint *const data2;
+ const gint *const *const data3;
+ const gint **const* data4;
+ volatile gint *const data5;
+ const gint *volatile data6;
+};
+
/* plain-old-data boxed types */
typedef struct _RegressTestSimpleBoxedA RegressTestSimpleBoxedA;
typedef struct _RegressTestSimpleBoxedB RegressTestSimpleBoxedB;