summaryrefslogtreecommitdiff
path: root/giscanner
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2010-09-08 15:23:22 -0400
committerColin Walters <walters@verbum.org>2010-09-08 15:23:22 -0400
commit43378bd809b7b9aa0f46f8257695b78ba0d28ff6 (patch)
tree37695fe0e00325053a1ad032060820b78aece4da /giscanner
parent51fe1536f23fb3b8ee2d8083036278c808128966 (diff)
downloadgobject-introspection-43378bd809b7b9aa0f46f8257695b78ba0d28ff6.tar.gz
scanner: Add notion of "private" structures, fix parsing
Diffstat (limited to 'giscanner')
-rw-r--r--giscanner/ast.py20
-rw-r--r--giscanner/girparser.py1
-rw-r--r--giscanner/transformer.py76
3 files changed, 61 insertions, 36 deletions
diff --git a/giscanner/ast.py b/giscanner/ast.py
index 6e9dc89f..13f290b3 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -373,6 +373,7 @@ returned."""
self._ctypes[node.symbol] = node
def remove(self, node):
+ assert node.namespace is self
if isinstance(node, Alias):
del self._aliases[node.name]
elif isinstance(node, Registered) and node.gtype_name is not None:
@@ -719,7 +720,8 @@ class Compound(Node, Registered):
gtype_name=None,
get_type=None,
c_symbol_prefix=None,
- disguised=False):
+ disguised=False,
+ private=False):
Node.__init__(self, name)
Registered.__init__(self, gtype_name, get_type)
self.ctype = ctype
@@ -727,7 +729,11 @@ class Compound(Node, Registered):
self.static_methods = []
self.fields = []
self.constructors = []
+ # This compound is: typedef struct Foo * Foo;
+ # note the * which hides that it's a pointer.
self.disguised = disguised
+ # The definition of this structure is not known.
+ self.private = private
self.gtype_name = gtype_name
self.get_type = get_type
self.c_symbol_prefix = c_symbol_prefix
@@ -771,13 +777,15 @@ class Record(Compound):
gtype_name=None,
get_type=None,
c_symbol_prefix=None,
- disguised=False):
+ disguised=False,
+ private=False):
Compound.__init__(self, name,
ctype=ctype,
gtype_name=gtype_name,
get_type=get_type,
c_symbol_prefix=c_symbol_prefix,
- disguised=disguised)
+ disguised=disguised,
+ private=private)
# If non-None, this record defines the FooClass C structure
# for some Foo GObject (or similar for GInterface)
self.is_gtype_struct_for = None
@@ -790,13 +798,15 @@ class Union(Compound):
gtype_name=None,
get_type=None,
c_symbol_prefix=None,
- disguised=False):
+ disguised=False,
+ private=False):
Compound.__init__(self, name,
ctype=ctype,
gtype_name=gtype_name,
get_type=get_type,
c_symbol_prefix=c_symbol_prefix,
- disguised=disguised)
+ disguised=disguised,
+ private=private)
class Boxed(Node, Registered):
diff --git a/giscanner/girparser.py b/giscanner/girparser.py
index ab2b29d6..442fc33d 100644
--- a/giscanner/girparser.py
+++ b/giscanner/girparser.py
@@ -334,6 +334,7 @@ class GIRParser(object):
compound = cls(node.attrib.get('name'),
ctype=node.attrib.get(_cns('type')),
disguised=node.attrib.get('disguised') == '1',
+ private=node.attrib.get('private') == '1',
gtype_name=node.attrib.get(_glibns('type-name')),
get_type=node.attrib.get(_glibns('get-type')),
c_symbol_prefix=node.attrib.get(_cns('symbol-prefix')))
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index 328d29e8..9e356203 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -50,7 +50,8 @@ class Transformer(object):
self._accept_unprefixed = accept_unprefixed
self._namespace = namespace
self._pkg_config_packages = set()
- self._typedefs_ns = {}
+ self._typedefs = {}
+ self._hidden_structures = {}
self._includes = {}
self._include_names = set()
self._includepaths = []
@@ -84,24 +85,25 @@ class Transformer(object):
if node:
self._append_new_node(node)
- # Now look through the namespace for things like
- # typedef struct _Foo Foo;
- # where we've never seen the struct _Foo. Just create
- # an empty structure for these as "disguised"
- # If we do have a class/interface, merge fields
- for typedef, compound in self._typedefs_ns.iteritems():
- ns_compound = self._namespace.get(compound.name)
- if not ns_compound:
- ns_compound = self._namespace.get('_' + compound.name)
- if (not ns_compound and isinstance(compound, (ast.Record, ast.Union))
- and len(compound.fields) == 0):
- disguised = ast.Record(compound.name, typedef, disguised=True)
- self._namespace.append(disguised)
- elif not ns_compound:
- self._namespace.append(compound)
- elif isinstance(ns_compound, (ast.Record, ast.Union)) and len(ns_compound.fields) == 0:
- ns_compound.fields = compound.fields
- self._typedefs_ns = None
+ for typedef, target_name in self._typedefs.iteritems():
+ if target_name.startswith('_'):
+ target = self._hidden_structures.get(target_name, None)
+ else:
+ continue
+ print "processing %r => %r, target=%r" % (typedef, target_name, target)
+ if target is None:
+ stub = ast.Record(typedef, typedef, private=True)
+ self._namespace.append(stub)
+ else:
+ target.name = typedef
+ self._namespace.append(target)
+ del self._hidden_structures[target_name]
+
+ for name, struct in self._hidden_structures.iteritems():
+ typedef = self._namespace.get(name[1:])
+ if not typedef:
+ message.warn_node(struct,
+"%r: Hidden structure with no corresponding typedef" % (name, ))
def set_include_paths(self, paths):
self._includepaths = list(paths)
@@ -282,7 +284,7 @@ raise ValueError."""
return '_' + name
return name
- def _traverse_one(self, symbol, stype=None):
+ def _traverse_one(self, symbol, stype=None, is_field=False):
assert isinstance(symbol, SourceSymbol), symbol
if stype is None:
@@ -292,13 +294,13 @@ raise ValueError."""
elif stype == CSYMBOL_TYPE_TYPEDEF:
return self._create_typedef(symbol)
elif stype == CSYMBOL_TYPE_STRUCT:
- return self._create_struct(symbol)
+ return self._create_struct(symbol, is_field=is_field)
elif stype == CSYMBOL_TYPE_ENUM:
return self._create_enum(symbol)
elif stype == CSYMBOL_TYPE_MEMBER:
return self._create_member(symbol)
elif stype == CSYMBOL_TYPE_UNION:
- return self._create_union(symbol)
+ return self._create_union(symbol, is_field=is_field)
elif stype == CSYMBOL_TYPE_CONST:
return self._create_const(symbol)
# Ignore variable declarations in the header
@@ -441,11 +443,11 @@ raise ValueError."""
node = self._create_typedef_callback(symbol)
elif (ctype == CTYPE_POINTER and
symbol.base_type.base_type.type == CTYPE_STRUCT):
- node = self._create_typedef_struct(symbol, disguised=True)
+ node = self._create_typedef_compound(ast.Struct, symbol, disguised=True)
elif ctype == CTYPE_STRUCT:
- node = self._create_typedef_struct(symbol)
+ node = self._create_typedef_compound(ast.Struct, symbol)
elif ctype == CTYPE_UNION:
- node = self._create_typedef_union(symbol)
+ node = self._create_typedef_compound(ast.Union, symbol)
elif ctype == CTYPE_ENUM:
return self._create_enum(symbol)
elif ctype in (CTYPE_TYPEDEF,
@@ -597,17 +599,29 @@ raise ValueError."""
const.add_symbol_reference(symbol)
return const
- def _create_typedef_struct(self, symbol, disguised=False):
+ def _create_typedef_compound(self, cls, symbol, disguised=False):
try:
name = self.strip_identifier(symbol.ident)
except TransformerException, e:
message.warn_symbol(symbol, e)
return None
- struct = ast.Record(name, symbol.ident, disguised=disguised)
- self._parse_fields(symbol, struct)
- struct.add_symbol_reference(symbol)
- self._typedefs_ns[symbol.ident] = struct
- return None
+
+ if disguised:
+ return cls(name, symbol.ident, disguised=True)
+
+ children = list(symbol.base_type.child_list)
+ if len(children) > 0:
+ compound = cls(name, symbol.ident, disguised)
+ self._parse_fields(symbol, compound)
+ compound.add_symbol_reference(symbol)
+ return compound
+ else:
+ try:
+ target_name = self.strip_identifier(symbol.base_type.name)
+ except TransformerException, e:
+ message.warn_symbol(symbol, e)
+ return None
+ self._typedefs[name] = target_name
def _create_typedef_union(self, symbol):
try: