summaryrefslogtreecommitdiff
path: root/giscanner/girparser.py
diff options
context:
space:
mode:
authorLucas Rocha <lucasr@gnome.org>2008-10-11 18:33:43 +0000
committerLucas Almeida Rocha <lucasr@src.gnome.org>2008-10-11 18:33:43 +0000
commit0be08ed820506a63b5a9342d52d695f977934145 (patch)
tree2955cbd94fba25494a18deedbf176a88e41a84a4 /giscanner/girparser.py
parentf1be097d3be66639374c160225f01cfd42275953 (diff)
downloadgobject-introspection-0be08ed820506a63b5a9342d52d695f977934145.tar.gz
Bug 554854: The --typelib-xml and --inject options should reuse giscanner
2008-10-11 Lucas Rocha <lucasr@gnome.org> Bug 554854: The --typelib-xml and --inject options should reuse giscanner parser/writer. * giscanner/ast.py: add constructor list to Struct and Union. Add new param in Return's contructor to define transfer. * giscanner/girparser.py: several additions to the parser in order to have parsing all nodes of the gir xml files. * tools/g-ir-scanner (typelib_xml_strip, inject): use gir parser and writer in --inject and --typelib-xml options. * giscanner/xmlwriter.py: ignore empty attributes instead of raising an error as this basically exposes a bug in GIRParser. This should be reverted as soon as the parser is fixed. svn path=/trunk/; revision=665
Diffstat (limited to 'giscanner/girparser.py')
-rw-r--r--giscanner/girparser.py103
1 files changed, 82 insertions, 21 deletions
diff --git a/giscanner/girparser.py b/giscanner/girparser.py
index 91416f0e..0d318c36 100644
--- a/giscanner/girparser.py
+++ b/giscanner/girparser.py
@@ -20,8 +20,8 @@
from xml.etree.cElementTree import parse
-from .ast import (Alias, Callback, Function, Parameter, Return, Union,
- Struct, Type, Array)
+from .ast import (Alias, Callback, Function, Field, Parameter, Property,
+ Return, Union, Struct, Type, Array, Namespace, Varargs)
from .glibast import (GLibEnum, GLibEnumMember, GLibFlags,
GLibInterface, GLibObject, GLibBoxedStruct,
GLibBoxedUnion, GLibBoxedOther)
@@ -45,29 +45,40 @@ def _cns(tag):
class GIRParser(object):
- def __init__(self, filename):
- self._nodes = []
+ def __init__(self, filename, initial_parse=True):
self._includes = set()
- self._namespace_name = None
+ self._namespace = None
+ self._shared_libraries = []
+ self._tree = parse(filename)
- tree = parse(filename)
- self._parse_api(tree.getroot())
+ if (initial_parse):
+ self.parse()
# Public API
- def get_namespace_name(self):
- return self._namespace_name
+ def parse(self):
+ self._includes.clear()
+ del self._namespace
+ del self._shared_libraries[:]
+
+ self._parse_api(self._tree.getroot())
+
+ def get_namespace(self):
+ return self._namespace
+
+ def get_shared_libraries(self):
+ return self._shared_libraries
def get_includes(self):
return self._includes
- def get_nodes(self):
- return self._nodes
+ def get_doc(self):
+ return self._tree
# Private
def _add_node(self, node):
- self._nodes.append(node)
+ self._namespace.nodes.append(node)
def _parse_api(self, root):
assert root.tag == _corens('repository')
@@ -76,7 +87,8 @@ class GIRParser(object):
self._includes.add(node.attrib['name'])
ns = root.find(_corens('namespace'))
assert ns is not None
- self._namespace_name = ns.attrib['name']
+ self._namespace = Namespace(ns.attrib['name'])
+ self._shared_libraries.extend(ns.attrib['shared-library'].split(','))
for child in ns.getchildren():
self._parse_node(child)
@@ -118,12 +130,20 @@ class GIRParser(object):
node.attrib[_glibns('type-name')],
node.attrib[_glibns('get-type')],
node.attrib.get(_cns('type')))
+ for iface in node.findall(_corens('implements')):
+ obj.interfaces.append(iface.attrib['name'])
for method in node.findall(_corens('method')):
obj.methods.append(self._parse_function(method, Function))
for ctor in node.findall(_corens('constructor')):
obj.constructors.append(self._parse_function(ctor, Function))
for callback in node.findall(_corens('callback')):
obj.fields.append(self._parse_function(callback, Callback))
+ for field in node.findall(_corens('field')):
+ obj.fields.append(self._parse_field(field))
+ for property in node.findall(_corens('property')):
+ obj.properties.append(self._parse_property(property))
+ for signal in node.findall(_glibns('signal')):
+ obj.signals.append(self._parse_function(signal, Function))
self._add_node(obj)
def _parse_function(self, node, klass):
@@ -131,11 +151,17 @@ class GIRParser(object):
returnnode = node.find(_corens('return-value'))
if not returnnode:
raise ValueError('node %r has no return-value' % (name, ))
- retval = Return(self._parse_type(returnnode))
+ transfer = False
+ transfer_param = returnnode.attrib.get('transfer-ownership')
+ if transfer_param is not None:
+ transfer = (transfer_param == '1')
+ retval = Return(self._parse_type(returnnode), transfer)
+ parameters_node = node.find(_corens('parameters'))
parameters = []
- for paramnode in node.findall('parameter'):
- parameters.append(Parameter(paramnode.attrib['name'],
- self._parse_type(paramnode)))
+ if (parameters_node is not None):
+ for paramnode in parameters_node.findall(_corens('parameter')):
+ parameters.append(Parameter(paramnode.attrib.get('name'),
+ self._parse_type(paramnode)))
if klass is Callback:
return klass(name, retval, parameters,
node.attrib.get(_cns('type')))
@@ -151,7 +177,15 @@ class GIRParser(object):
node.attrib.get(_cns('type')))
else:
struct = Struct(node.attrib['name'],
- node.attrib[_cns('type')])
+ node.attrib.get(_cns('type')))
+ for field in node.findall(_corens('field')):
+ struct.fields.append(self._parse_field(field))
+ for callback in node.findall(_corens('callback')):
+ struct.fields.append(self._parse_function(callback, Callback))
+ for method in node.findall(_corens('method')):
+ struct.fields.append(self._parse_function(method, Function))
+ for ctor in node.findall(_corens('constructor')):
+ struct.constructors.append(self._parse_function(ctor, Function))
self._add_node(struct)
def _parse_union(self, node):
@@ -162,7 +196,15 @@ class GIRParser(object):
node.attrib.get(_cns('type')))
else:
struct = Union(node.attrib['name'],
- node.attrib[_cns('type')])
+ node.attrib.get(_cns('type')))
+ for callback in node.findall(_corens('callback')):
+ struct.fields.append(self._parse_function(callback, Callback))
+ for field in node.findall(_corens('field')):
+ struct.fields.append(self._parse_field(field))
+ for method in node.findall(_corens('method')):
+ struct.fields.append(self._parse_function(method, Function))
+ for ctor in node.findall(_corens('constructor')):
+ struct.constructors.append(self._parse_function(ctor, Function))
self._add_node(struct)
def _parse_type(self, node):
@@ -172,8 +214,11 @@ class GIRParser(object):
typenode.attrib.get(_cns('type')))
typenode = node.find(_corens('array'))
if typenode is not None:
- return Array(typenode.attrib[_cns('type')],
+ return Array(typenode.attrib.get(_cns('type')),
self._parse_type(typenode))
+ typenode = node.find(_corens('varargs'))
+ if typenode is not None:
+ return Varargs()
raise ValueError("Couldn't parse type of node %r; children=%r",
node, list(node))
@@ -189,10 +234,26 @@ class GIRParser(object):
obj.fields.append(self._parse_function(callback, Callback))
self._add_node(obj)
+ def _parse_field(self, node):
+ type_node = self._parse_type(node)
+ return Field(node.attrib['name'],
+ type_node,
+ type_node.ctype)
+
+ def _parse_property(self, node):
+ type_node = self._parse_type(node)
+ return Property(node.attrib['name'],
+ type_node.name,
+ node.attrib.get('readable') != '0',
+ node.attrib.get('writable') == '1',
+ node.attrib.get('construct') == '1',
+ node.attrib.get('construct-only') == '1',
+ type_node.ctype)
+
def _parse_member(self, node):
return GLibEnumMember(node.attrib['name'],
node.attrib['value'],
- node.attrib[_cns('identifier')],
+ node.attrib.get(_cns('identifier')),
node.attrib.get(_glibns('nick')))
def _parse_enumeration_bitfield(self, node):