GLIB_LIBDIR=`pkg-config --variable=libdir glib-2.0`
glib-2.0.gir: $(G_IR_SCANNER) $(G_IR_SCANNER_FILES)
$(G_IR_SCANNER) -v --namespace GLib \
+ --noclosure \
--output $@ \
--strip-prefix=g \
-I$(GLIB_INCLUDEDIR) \
# gobject
GOBJECT_INCLUDEDIR=`pkg-config --variable=includedir gobject-2.0`/glib-2.0
GOBJECT_LIBDIR=`pkg-config --variable=libdir gobject-2.0`
-gobject-2.0.gir: $(G_IR_SCANNER) $(G_IR_SCANNER_FILES)
+gobject-2.0.gir: glib-2.0.gir $(G_IR_SCANNER) $(G_IR_SCANNER_FILES)
$(G_IR_SCANNER) -v --namespace GObject \
+ --noclosure \
--output $@ \
--strip-prefix=g \
--include=$(builddir)/glib-2.0.gir \
GIO_LIBDIR=`pkg-config --variable=libdir gio-2.0`
gio-2.0.gir: $(G_IR_SCANNER) $(G_IR_SCANNER_FILES)
$(G_IR_SCANNER) -v --namespace Gio \
+ --noclosure \
--output $@ \
--strip-prefix=g \
--include=$(builddir)/glib-2.0.gir \
"""
##
-## Types
+## Basic types, modeled on GITypeTag but not equivalent
##
-# Basic types
+TYPE_NONE = 'none' # We differ from repository on these first two
+TYPE_ANY = 'any'
+TYPE_BOOLEAN = 'boolean'
TYPE_INT8 = 'int8'
TYPE_UINT8 = 'uint8'
TYPE_INT16 = 'int16'
TYPE_UINT = 'uint'
TYPE_INT32 = 'int32'
TYPE_UINT32 = 'uint32'
-TYPE_LONG = 'long'
-TYPE_ULONG = 'ulong'
TYPE_INT64 = 'int64'
TYPE_UINT64 = 'uint64'
-
-# Floating-point
+TYPE_LONG = 'long'
+TYPE_ULONG = 'ulong'
+TYPE_SSIZET = 'ssize_t'
+TYPE_SIZET = 'size_t'
TYPE_FLOAT = 'float'
TYPE_DOUBLE = 'double'
+TYPE_STRING = 'string' # requires zero-terminated
+TYPE_FILENAME = 'filename'
+
+BASIC_GIR_TYPES = [TYPE_BOOLEAN, TYPE_INT8, TYPE_UINT8, TYPE_INT16,
+ TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64,
+ TYPE_UINT64, TYPE_INT, TYPE_UINT, TYPE_LONG,
+ TYPE_ULONG, TYPE_SSIZET, TYPE_SIZET, TYPE_FLOAT,
+ TYPE_DOUBLE]
+GIR_TYPES = [TYPE_NONE, TYPE_ANY]
+GIR_TYPES.extend(BASIC_GIR_TYPES)
+GIR_TYPES.extend([TYPE_STRING, TYPE_FILENAME])
# Higher-level data types
-TYPE_NONE = 'none'
-TYPE_ANY = 'any' # CORBA Any/Variant/GValue, holds anything.
-TYPE_BOOLEAN = 'boolean' # True/False
-TYPE_STRING = 'string' # Sequence of characters
TYPE_SEQUENCE = 'sequence' # Sequence of something
-TYPE_CHAR = 'char' # Character
-TYPE_UCHAR = 'uchar' # Unsigned Character
-TYPE_SIZE = 'size' # Size type (memory, buffer etc)
-TYPE_SSIZE = 'ssize'
# Wide/Unicode
TYPE_UCHAR = 'uchar'
TYPE_USTRING = 'ustring'
-# Domain specific, but practically useful
-TYPE_FILENAME = 'filename'
-
##
## Parameters
##
PARAM_DIRECTION_INOUT = 'inout'
type_names = {}
+for name in GIR_TYPES:
+ type_names[name] = name
# C
-type_names['char'] = TYPE_CHAR
-type_names['unsigned char'] = TYPE_UCHAR
+type_names['char'] = TYPE_INT8
+type_names['unsigned char'] = TYPE_UINT8
type_names['short'] = TYPE_INT16
type_names['unsigned short'] = TYPE_UINT16
-type_names['int'] = TYPE_INT32
-type_names['unsigned int'] = TYPE_UINT32
+type_names['int'] = TYPE_INT
+type_names['unsigned int'] = TYPE_UINT
type_names['long'] = TYPE_LONG
type_names['unsigned long'] = TYPE_ULONG
type_names['float'] = TYPE_FLOAT
type_names['char*'] = TYPE_STRING
type_names['void*'] = TYPE_ANY
type_names['void'] = TYPE_NONE
-type_names['size_t'] = TYPE_SIZE
-type_names['ssize_t'] = TYPE_SSIZE
-
-# GIR names
-type_names['none'] = TYPE_NONE
-type_names['string'] = TYPE_STRING
-type_names['int32'] = TYPE_INT32
-type_names['uint32'] = TYPE_UINT32
-type_names['any'] = TYPE_ANY
+type_names['size_t'] = TYPE_SIZET
+type_names['ssize_t'] = TYPE_SSIZET
def type_name_from_ctype(ctype):
def __init__(self, name, ctype=None):
Node.__init__(self, name)
self.ctype = ctype
+ self.resolved = False
class Alias(Node):
Type.__init__(self, name, ctype)
self.element_type = element_type
self.transfer = False
+
+ def __repr__(self):
+ return 'Sequence(%r of %r)' % (self.name, self.element_type, )
obj = klass(node.attrib['name'],
node.attrib.get('parent'),
node.attrib[_glibns('type-name')],
- node.attrib[_glibns('get-type')])
+ node.attrib[_glibns('get-type')],
+ node.attrib.get(_cns('type')))
for method in node.findall(_corens('method')):
obj.methods.append(self._parse_function(method, Function))
for ctor in node.findall(_corens('constructor')):
def _parse_boxed(self, node):
obj = GLibBoxed(node.attrib[_glibns('name')],
node.attrib[_glibns('type-name')],
- node.attrib[_glibns('get-type')])
+ node.attrib[_glibns('get-type')],
+ node.attrib.get(_cns('type')))
for method in node.findall(_corens('method')):
obj.methods.append(self._parse_function(method, Function))
for ctor in node.findall(_corens('constructor')):
attrs.append(('transfer-ownership',
str(int(return_.transfer))))
with self.tagcontext('return-value', attrs):
- if isinstance(return_.type, Sequence):
- self._write_sequence(return_.type)
- else:
- self._write_type(return_.type)
+ self._write_type(return_.type)
def _write_parameters(self, parameters):
if not parameters:
with self.tagcontext('parameter', attrs):
self._write_type(parameter.type)
- def _write_type(self, ntype):
- attrs = [('name', ntype.name)]
- # FIXME: figure out if type references a basic type
- # or a boxed/class/interface etc. and skip
- # writing the ctype if the latter.
- if ntype.ctype is not None:
- attrs.append(('c:type', ntype.ctype))
- self.write_tag('type', attrs)
-
- def _write_sequence(self, sequence):
- attrs = []
- if sequence.transfer:
- attrs.append(('transfer-ownership',
- str(int(sequence.transfer))))
- with self.tagcontext('sequence', attrs):
- attrs = [('c:identifier', sequence.element_type)]
- self.write_tag('element-type', attrs)
+ def _write_type(self, ntype, relation=None):
+ if isinstance(ntype, basestring):
+ typename = ntype
+ type_cname = None
+ else:
+ typename = ntype.name
+ type_cname = ntype.ctype
+ attrs = [('name', typename)]
+ if relation:
+ attrs.append(('relation', relation))
+ if isinstance(ntype, Sequence):
+ if ntype.transfer:
+ attrs.append(('transfer-ownership',
+ str(int(ntype.transfer))))
+ with self.tagcontext('type', attrs):
+ self._write_type(ntype.element_type, relation="element")
+ else:
+ # FIXME: figure out if type references a basic type
+ # or a boxed/class/interface etc. and skip
+ # writing the ctype if the latter.
+ if type_cname is not None:
+ attrs.append(('c:type', type_cname))
+ self.write_tag('type', attrs)
def _write_enum(self, enum):
attrs = [('name', enum.name),
from .ast import (
type_names,
TYPE_STRING, TYPE_INT8, TYPE_UINT8, TYPE_INT16, TYPE_UINT16,
- TYPE_UINT32, TYPE_INT32, TYPE_LONG, TYPE_ULONG, TYPE_INT64,
- TYPE_UINT64, TYPE_FLOAT, TYPE_INT, TYPE_UINT,
- TYPE_DOUBLE, TYPE_BOOLEAN, TYPE_ANY, TYPE_SIZE, TYPE_SSIZE)
+ TYPE_INT, TYPE_UINT, TYPE_UINT32, TYPE_INT32, TYPE_LONG,
+ TYPE_ULONG, TYPE_INT64, TYPE_UINT64, TYPE_FLOAT,
+ TYPE_DOUBLE, TYPE_BOOLEAN, TYPE_ANY, TYPE_SSIZET,
+ TYPE_SIZET)
+
# Glib type names
type_names['gchararray'] = TYPE_STRING
type_names['gboolean'] = TYPE_BOOLEAN
type_names['gpointer'] = TYPE_ANY
type_names['gconstpointer'] = TYPE_ANY
-type_names['gsize'] = TYPE_SIZE
-type_names['gssize'] = TYPE_SSIZE
+type_names['gsize'] = TYPE_SIZET
+type_names['gssize'] = TYPE_SSIZET
class GLibEnum(Enum):
class GLibObject(Class):
- def __init__(self, name, parent, type_name, get_type):
+ def __init__(self, name, parent, type_name, get_type, ctype=None):
Class.__init__(self, name, parent)
- self.ctype = type_name
self.type_name = type_name
self.get_type = get_type
self.signals = []
+ self.ctype = ctype or type_name
class GLibBoxed(Struct):
- def __init__(self, name, type_name, get_type):
+ def __init__(self, name, type_name, get_type, ctype=None):
Struct.__init__(self, name, get_type)
- self.ctype = name
self.constructors = []
self.methods = []
self.type_name = type_name
self.symbol = type_name
self.get_type = get_type
+ self.ctype = ctype or type_name
class GLibInterface(Interface):
- def __init__(self, name, parent, type_name, get_type):
+ def __init__(self, name, parent, type_name, get_type,
+ ctype=None):
Interface.__init__(self, name, parent)
- self.ctype = type_name
self.type_name = type_name
self.get_type = get_type
self.signals = []
+ self.ctype = ctype or type_name
class GLibProperty(Property):
#
import ctypes
-import sys
from . import cgobject
-from .odict import odict
from .ast import (Callback, Enum, Function, Member, Namespace, Parameter,
- Property, Return, Struct, Type, Alias, type_name_from_ctype)
+ Sequence, Property, Return, Struct, Type, Alias,
+ type_name_from_ctype)
+from .transformer import Names
from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
GLibInterface, GLibObject, GLibSignal, type_names)
from .utils import extract_libtool, to_underscores
+class Unresolved(object):
+
+ def __init__(self, target):
+ self.target = target
+
+
+class UnknownTypeError(Exception):
+ pass
+
+
class GLibTransformer(object):
- def __init__(self, transformer):
+ def __init__(self, transformer, noclosure=False):
self._transformer = transformer
self._namespace_name = None
- self._aliases = []
- self._output_ns = odict()
+ self._names = Names()
self._libraries = []
self._failed_types = {}
- self._internal_types = {}
+ self._noclosure = noclosure
self._validating = False
# Public API
# Second pass, delete class structures, resolve
# all types we now know about
- nodes = list(self._output_ns.itervalues())
- for node in nodes:
+ nodes = list(self._names.names.itervalues())
+ for (ns, node) in nodes:
self._resolve_node(node)
# associate GtkButtonClass with GtkButton
if isinstance(node, Struct):
self._pair_class_struct(node)
- for alias in self._aliases:
+ for (ns, alias) in self._names.aliases.itervalues():
self._resolve_alias(alias)
# Third pass; ensure all types are known
- if 0:
+ if not self._noclosure:
self._validate(nodes)
# Create a new namespace with what we found
namespace = Namespace(namespace.name)
- namespace.nodes = self._aliases + list(self._output_ns.itervalues())
+ namespace.nodes = map(lambda x: x[1], self._names.aliases.itervalues())
+ for (ns, x) in self._names.names.itervalues():
+ namespace.nodes.append(x)
return namespace
# Private
def _add_attribute(self, node, replace=False):
node_name = node.name
- if (not replace) and node_name in self._output_ns:
+ if (not replace) and node_name in self._names.names:
return
- self._output_ns[node_name] = node
+ self._names.names[node_name] = (None, node)
def _remove_attribute(self, name):
- del self._output_ns[name]
+ del self._names.names[name]
def _get_attribute(self, name):
- return self._output_ns.get(name)
+ node = self._names.names.get(name)
+ if node:
+ return node[1]
+ return None
def _register_internal_type(self, type_name, node):
- self._internal_types[type_name] = node
+ self._names.type_names[type_name] = (None, node)
# Helper functions
def _create_type(self, type_id):
ctype = cgobject.type_name(type_id)
type_name = type_name_from_ctype(ctype)
+ type_name = type_name.replace('*', '')
type_name = self._resolve_type_name(type_name)
return Type(type_name, ctype)
+ def _resolve_gtypename(self, gtype_name):
+ try:
+ return self._transformer.gtypename_to_giname(gtype_name,
+ self._names)
+ except KeyError, e:
+ return Unresolved(gtype_name)
+
def _create_gobject(self, node):
type_name = 'G' + node.name
if type_name == 'GObject':
- parent_type_name = None
+ parent_gitype = None
symbol = 'intern'
else:
type_id = cgobject.type_from_name(type_name)
parent_type_name = cgobject.type_name(
cgobject.type_parent(type_id))
+ parent_gitype = self._resolve_gtypename(parent_type_name)
symbol = to_underscores(type_name).lower() + '_get_type'
- node = GLibObject(node.name, parent_type_name, type_name, symbol)
+ node = GLibObject(node.name, parent_gitype, type_name, symbol)
type_id = cgobject.TYPE_OBJECT
self._introspect_properties(node, type_id)
self._introspect_signals(node, type_id)
print 'GOBJECT BUILDER: Unhandled node:', node
def _parse_alias(self, alias):
- self._aliases.append(alias)
+ self._names.aliases[alias.name] = (None, alias)
def _parse_enum(self, enum):
self._add_attribute(enum)
elif struct.name in g_internal_names:
# Avoid duplicates
return
- node = self._output_ns.get(struct.name)
+ node = self._names.names.get(struct.name)
if node is None:
self._add_attribute(struct, replace=True)
return
+ (ns, node) = node
node.fields = struct.fields[:]
def _parse_callback(self, callback):
ctype = self._transformer.ctype_of(param).replace('*', '')
uscored = to_underscores(self._strip_class_suffix(ctype)).lower()
if uscored in self._failed_types:
- print >> sys.stderr, "failed type: %r" % (param, )
+ print "Warning: failed type: %r" % (param, )
return True
return False
if self._arg_is_failed(maybe_class):
print "WARNING: deleting no-type %r" % (maybe_class.name, )
- del self._output_ns[maybe_class.name]
+ del self._names.names[maybe_class.name]
return
name = self._resolve_type_name(name)
resolved = self._transformer.strip_namespace_object(name)
- pair_class = self._output_ns.get(resolved)
+ pair_class = self._get_attribute(resolved)
if pair_class and isinstance(pair_class,
(GLibObject, GLibBoxed, GLibInterface)):
-
- del self._output_ns[maybe_class.name]
+ del self._names.names[maybe_class.name]
for field in maybe_class.fields[1:]:
pair_class.fields.append(field)
return
name = self._transformer.strip_namespace_object(maybe_class.name)
- pair_class = self._output_ns.get(name)
+ pair_class = self._get_attribute(name)
if pair_class and isinstance(pair_class,
(GLibObject, GLibBoxed, GLibInterface)):
- del self._output_ns[maybe_class.name]
+ del self._names.names[maybe_class.name]
# Introspection
def _introspect_object(self, type_id, symbol):
type_name = cgobject.type_name(type_id)
parent_type_name = cgobject.type_name(cgobject.type_parent(type_id))
+ parent_gitype = self._resolve_gtypename(parent_type_name)
node = GLibObject(
self._transformer.strip_namespace_object(type_name),
- self._resolve_type_name(parent_type_name),
+ parent_gitype,
type_name, symbol)
self._introspect_properties(node, type_id)
self._introspect_signals(node, type_id)
def _introspect_interface(self, type_id, symbol):
type_name = cgobject.type_name(type_id)
parent_type_name = cgobject.type_name(cgobject.type_parent(type_id))
+ if parent_type_name == 'GInterface':
+ parent_gitype = None
+ else:
+ parent_gitype = self._resolve_gtypename(parent_type_name)
node = GLibInterface(
self._transformer.strip_namespace_object(type_name),
- self._resolve_type_name(parent_type_name),
+ parent_gitype,
type_name, symbol)
self._introspect_properties(node, type_id)
self._introspect_signals(node, type_id)
# Resolver
def _resolve_type_name(self, type_name):
- type_name = type_name.replace('*', '')
- possible_name = self._transformer.resolve_type_name(type_name)
- if possible_name != type_name:
- return possible_name
- possible_node = self._internal_types.get(type_name)
- if possible_node:
- return possible_node.name
- return type_name
-
- def _validate_type(self, name):
+ res = self._transformer.resolve_type_name_full
+ try:
+ return res(type_name, None, self._names)
+ except KeyError, e:
+ return self._transformer.resolve_type_name(type_name, None)
+
+ def _validate_type_name(self, name):
if name in type_names:
return True
if name.find('.') >= 0:
return True
- if name in self._internal_types:
+ if name in self._names.aliases:
return True
- if name in self._aliases:
- return True
- if name in self._output_ns:
+ if name in self._names.names:
return True
return False
+ def _validate_type(self, ptype):
+ if isinstance(ptype, Sequence):
+ etype = ptype.element_type
+ if isinstance(etype, Sequence):
+ return self._validate_type(etype)
+ return self._validate_type_name(etype)
+ return self._validate_type_name(ptype.name)
+
+ def _resolve_param_type_validate(self, ptype):
+ ptype = self._resolve_param_type(ptype)
+ if self._validating and not self._validate_type(ptype):
+ raise UnknownTypeError("Unknown type %r" % (ptype, ))
+ return ptype
+
def _resolve_param_type(self, ptype):
- ptype.name = ptype.name.replace('*', '')
- type_name = ptype.name
- possible_node = self._internal_types.get(type_name)
- if possible_node:
- ptype.name = possible_node.name
- else:
- ptype = self._transformer.resolve_param_type(ptype)
- if self._validating and not self._validate_type(ptype.name):
- raise ValueError("Unknown type %r" % (ptype.name, ))
+ try:
+ return self._transformer.resolve_param_type_full(ptype,
+ self._names)
+ except KeyError, e:
+ return self._transformer.resolve_param_type(ptype)
return ptype
def _resolve_node(self, node):
for field in node.fields:
self._resolve_field(field)
+ def _resolve_parent(self, node):
+ if not isinstance(node, (GLibInterface, GLibObject)):
+ raise AssertionError
+ if isinstance(node.parent, Unresolved):
+ node.parent = \
+ self._transformer.gtypename_to_giname(node.parent.target,
+ self._names)
+
def _resolve_glib_interface(self, node):
+ self._resolve_parent(node)
self._resolve_methods(node.methods)
self._resolve_properties(node.properties)
self._resolve_signals(node.signals)
def _resolve_glib_object(self, node):
+ self._resolve_parent(node)
self._resolve_constructors(node.constructors)
self._resolve_methods(node.methods)
self._resolve_properties(node.properties)
return
field.type = self._resolve_param_type(field.type)
- def _resolve_alias(self, field):
- field.target = self._resolve_type_name(field.target)
+ def _resolve_alias(self, alias):
+ alias.target = self._resolve_type_name(alias.target)
# Validation
def _validate(self, nodes):
- nodes = list(self._output_ns.itervalues())
+ nodes = list(self._names.names.itervalues())
i = 0
self._validating = True
while True:
print "Type resolution; pass=%d" % (i, )
initlen = len(nodes)
- nodes = list(self._output_ns.itervalues())
+ nodes = list(self._names.names.itervalues())
for node in nodes:
try:
self._resolve_node(node)
- except ValueError, e:
+ except UnknownTypeError, e:
print "WARNING: %s: Deleting %r" % (e, node)
self._remove_attribute(node.name)
if len(nodes) == initlen:
from giscanner.ast import (Callback, Enum, Function, Namespace, Member,
Parameter, Return, Sequence, Struct, Field,
- Type, Alias, Interface, Class,
- type_name_from_ctype)
+ Type, Alias, Interface, Class, Node,
+ type_name_from_ctype, type_names)
from .glibast import GLibBoxed
from giscanner.sourcescanner import (
SourceSymbol, ctype_name, CTYPE_POINTER,
CSYMBOL_TYPE_FUNCTION, CSYMBOL_TYPE_TYPEDEF, CSYMBOL_TYPE_STRUCT,
CSYMBOL_TYPE_ENUM, CSYMBOL_TYPE_UNION, CSYMBOL_TYPE_OBJECT,
CSYMBOL_TYPE_MEMBER)
+from .odict import odict
from .utils import strip_common_prefix
pass
+class Names(object):
+ names = property(lambda self: self._names)
+ aliases = property(lambda self: self._aliases)
+ type_names = property(lambda self: self._type_names)
+ ctypes = property(lambda self: self._ctypes)
+
+ def __init__(self):
+ super(Names, self).__init__()
+ self._names = odict() # Maps from GIName -> (namespace, node)
+ self._aliases = {} # Maps from GIName -> GIName
+ self._type_names = {} # Maps from GTName -> (namespace, node)
+ self._ctypes = {} # Maps from CType -> (namespace, node)
+
+
class Transformer(object):
def __init__(self, generator, namespace_name):
self.generator = generator
self._namespace = Namespace(namespace_name)
- self._output_ns = {}
- self._alias_names = {} # Maps from GIName -> GIName
- self._type_names = {} # Maps from GTName -> (namespace, node)
- self._ctype_names = {} # Maps from CType -> (namespace, node)
+ self._names = Names()
self._typedefs_ns = {}
self._strip_prefix = ''
- def get_type_names(self):
- return self._type_names
-
- def get_alias_names(self):
- return self._alias_names
+ def get_names(self):
+ return self._names
def set_strip_prefix(self, strip_prefix):
self._strip_prefix = strip_prefix
nsname = parser.get_namespace_name()
for node in parser.get_nodes():
if isinstance(node, Alias):
- self._alias_names[node.ctype] = (nsname, node)
+ self._names.aliases[node.name] = (nsname, node)
elif isinstance(node, (GLibBoxed, Interface, Class)):
- self._type_names[node.type_name] = (nsname, node)
- elif hasattr(node, 'ctype'):
- self._ctype_names[node.ctype] = (nsname, node)
+ self._names.type_names[node.type_name] = (nsname, node)
+ self._names.names[node.name] = (nsname, node)
+ if hasattr(node, 'ctype'):
+ self._names.ctypes[node.ctype] = (nsname, node)
elif hasattr(node, 'symbol'):
- self._ctype_names[node.symbol] = (nsname, node)
- else:
- self._type_names[node.name] = (nsname, node)
+ self._names.ctypes[node.symbol] = (nsname, node)
def strip_namespace_object(self, name):
prefix = self._namespace.name.lower()
if node.name.startswith('_'):
return
self._namespace.nodes.append(node)
- self._output_ns[node.name] = node
+ self._names.names[node.name] = (None, node)
def _strip_namespace_func(self, name):
prefix = self._namespace.name.lower() + '_'
enum_name = symbol.ident[-len(enum_name):]
enum_name = self._remove_prefix(enum_name)
enum = Enum(enum_name, symbol.ident, members)
- self._type_names[symbol.ident] = (None, enum)
+ self._names.type_names[symbol.ident] = (None, enum)
return enum
def _create_object(self, symbol):
elif ctype == 'FILE*':
raise SkipError
type_name = type_name_from_ctype(ctype)
+ type_name = type_name.replace('*', '')
resolved_type_name = self.resolve_type_name(type_name)
return Type(resolved_type_name, ctype)
return_.transfer = True
elif option.startswith('seq '):
value, element_options = option[3:].split(None, 2)
- element_type = self._parse_type_annotation(value)
+ c_element_type = self._parse_type_annotation(value)
+ element_type = c_element_type.replace('*', '')
+ element_type = self.resolve_type_name(element_type,
+ c_element_type)
seq = Sequence(rtype.name,
type_name_from_ctype(rtype.name),
element_type)
return item.name
return '%s.%s' % (nsname, item.name)
- def resolve_type_name(self, type_name, ctype=None):
- type_name = type_name.replace('*', '')
+ def _resolve_type_name_1(self, type_name, ctype, names):
+ # First look using the built-in names
+ if ctype:
+ try:
+ return type_names[ctype]
+ except KeyError, e:
+ pass
+ try:
+ return type_names[type_name]
+ except KeyError, e:
+ pass
type_name = self.strip_namespace_object(type_name)
- resolved = self._alias_names.get(type_name)
+ resolved = names.aliases.get(type_name)
if resolved:
return self._typepair_to_str(resolved)
- resolved = self._type_names.get(type_name)
+ resolved = names.names.get(type_name)
if resolved:
return self._typepair_to_str(resolved)
if ctype:
ctype = ctype.replace('*', '')
- resolved = self._ctype_names.get(ctype)
+ resolved = names.ctypes.get(ctype)
if resolved:
return self._typepair_to_str(resolved)
- return type_name
+ raise KeyError("failed to find %r" % (type_name, ))
+
+ def resolve_type_name_full(self, type_name, ctype,
+ names):
+ try:
+ return self._resolve_type_name_1(type_name, ctype, names)
+ except KeyError, e:
+ try:
+ return self._resolve_type_name_1(type_name, ctype, self._names)
+ except KeyError, e:
+ return type_name
+
+ def resolve_type_name(self, type_name, ctype=None):
+ try:
+ return self.resolve_type_name_full(type_name, ctype, self._names)
+ except KeyError, e:
+ return type_name
+
+ def gtypename_to_giname(self, gtname, names):
+ resolved = names.type_names.get(gtname)
+ if resolved:
+ return self._typepair_to_str(resolved)
+ resolved = self._names.type_names.get(gtname)
+ if resolved:
+ return self._typepair_to_str(resolved)
+ raise KeyError("Failed to resolve GType name: %r" % (gtname, ))
def ctype_of(self, obj):
if hasattr(obj, 'ctype'):
else:
return None
- def resolve_param_type(self, ptype):
- ptype.name = self.resolve_type_name(ptype.name,
- self.ctype_of(ptype))
+ def resolve_param_type_full(self, ptype, names):
+ if isinstance(ptype, Sequence):
+ ptype.element_type = \
+ self.resolve_param_type_full(ptype.element_type, names)
+ elif isinstance(ptype, Node):
+ ptype.name = self.resolve_type_name_full(ptype.name,
+ self.ctype_of(ptype),
+ names)
+ elif isinstance(ptype, basestring):
+ return self.resolve_type_name_full(ptype, None, names)
+ else:
+ raise AssertionError("Unhandled param: %r" % (ptype, ))
return ptype
+
+ def resolve_param_type(self, ptype):
+ try:
+ return self.resolve_param_type_full(ptype, self._names)
+ except KeyError, e:
+ return ptype
</method>
<method name="get_strings" c:identifier="foo_object_get_strings">
<return-value>
- <sequence transfer-ownership="1">
- <element-type c:identifier="char*"/>
- </sequence>
+ <type name="GLib.List" transfer-ownership="1">
+ <type name="string" relation="element"/>
+ </type>
</return-value>
<parameters>
<parameter name="object">
</method>
<method name="get_objects" c:identifier="foo_object_get_objects">
<return-value>
- <sequence transfer-ownership="1">
- <element-type c:identifier="FooObject*"/>
- </sequence>
+ <type name="GLib.SList" transfer-ownership="1">
+ <type name="Object" relation="element"/>
+ </type>
</return-value>
<parameters>
<parameter name="object">
<type name="Object" c:type="FooObject*"/>
</parameter>
<parameter name="first_param">
- <type name="int32" c:type="int"/>
+ <type name="int" c:type="int"/>
</parameter>
</parameters>
</callback>
</enumeration>
<function name="enum_type_method" c:identifier="foo_enum_type_method">
<return-value>
- <type name="int32" c:type="int"/>
+ <type name="int" c:type="int"/>
</return-value>
<parameters>
<parameter name="foo_enum">
</return-value>
<parameters>
<parameter name="x">
- <type name="int32" c:type="int"/>
+ <type name="int" c:type="int"/>
</parameter>
</parameters>
</function>
<member name="deux" value="2" c:identifier="FOO_ENUM_DEUX"/>
<member name="trois" value="3" c:identifier="FOO_ENUM_TROIS"/>
</enumeration>
- <glib:boxed c:type="Boxed"
+ <glib:boxed c:type="FooBoxed"
glib:name="Boxed"
glib:type-name="FooBoxed"
glib:get-type="foo_boxed_get_type">
<type name="StructPrivate" c:type="FooStructPrivate*"/>
</field>
<field name="member">
- <type name="int32" c:type="int"/>
+ <type name="int" c:type="int"/>
</field>
</record>
<record name="StructPrivate" c:type="FooStructPrivate"/>
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose",
help="be verbose")
+ parser.add_option("", "--noclosure",
+ action="store_true", dest="noclosure",# default=True,
+ help="do not delete unknown types")
+
group = optparse.OptionGroup(parser, "Preprocessor options")
group.add_option("-I", help="Pre-processor include file",
# Transform the C AST nodes into higher level
# GLib/GObject nodes
- glibtransformer = GLibTransformer(transformer)
+ glibtransformer = GLibTransformer(transformer, noclosure=options.noclosure)
if options.libraries:
for library in options.libraries:
glibtransformer.add_library(library)