gobject-introspection r665 - in trunk: . giscanner tools
- From: lucasr svn gnome org
- To: svn-commits-list gnome org
- Subject: gobject-introspection r665 - in trunk: . giscanner tools
- Date: Sat, 11 Oct 2008 18:33:43 +0000 (UTC)
Author: lucasr
Date: Sat Oct 11 18:33:43 2008
New Revision: 665
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=665&view=rev
Log:
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.
Modified:
trunk/ChangeLog
trunk/giscanner/ast.py
trunk/giscanner/girparser.py
trunk/giscanner/girwriter.py
trunk/giscanner/transformer.py
trunk/giscanner/xmlwriter.py
trunk/tools/g-ir-scanner
Modified: trunk/giscanner/ast.py
==============================================================================
--- trunk/giscanner/ast.py (original)
+++ trunk/giscanner/ast.py Sat Oct 11 18:33:43 2008
@@ -260,6 +260,7 @@
def __init__(self, name, symbol):
Node.__init__(self, name)
self.fields = []
+ self.constructors = []
self.symbol = symbol
@@ -276,11 +277,11 @@
class Return(Node):
- def __init__(self, rtype):
+ def __init__(self, rtype, transfer=False):
Node.__init__(self)
self.type = rtype
self.transfer = isinstance(rtype, (List, Map, Array)) or \
- rtype.name in ('utf8', 'filename')
+ rtype.name in ('utf8', 'filename') or transfer
def __repr__(self):
return 'Return(%r)' % (self.type, )
@@ -369,6 +370,7 @@
def __init__(self, name, symbol):
Node.__init__(self, name)
self.fields = []
+ self.constructors = []
self.symbol = symbol
def __repr__(self):
Modified: trunk/giscanner/girparser.py
==============================================================================
--- trunk/giscanner/girparser.py (original)
+++ trunk/giscanner/girparser.py Sat Oct 11 18:33:43 2008
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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):
Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py (original)
+++ trunk/giscanner/girwriter.py Sat Oct 11 18:33:43 2008
@@ -189,16 +189,18 @@
self.write_tag('type', attrs)
def _write_enum(self, enum):
- attrs = [('name', enum.name),
- ('c:type', enum.symbol)]
+ attrs = [('name', enum.name)]
self._append_deprecated(enum, attrs)
- tag_name = 'enumeration'
- if isinstance(enum, GLibEnum):
+ if isinstance(enum, GLibFlags):
+ tag_name = 'bitfield'
+ else:
+ tag_name = 'enumeration'
+ if isinstance(enum, GLibEnum) or isinstance(enum, GLibFlags):
attrs.extend([('glib:type-name', enum.type_name),
- ('glib:get-type', enum.get_type)])
- if isinstance(enum, GLibFlags):
- tag_name = 'bitfield'
-
+ ('glib:get-type', enum.get_type),
+ ('c:type', enum.ctype)])
+ else:
+ attrs.append(('c:type', enum.symbol))
with self.tagcontext(tag_name, attrs):
for member in enum.members:
self._write_member(member)
@@ -305,8 +307,11 @@
self._write_boxed_ctors_methods(union)
def _write_field(self, field):
- # FIXME: Just function
- if isinstance(field, (Callback, Function)):
+ if isinstance(field, Function):
+ self._write_method(field)
+ return
+
+ if isinstance(field, Callback):
self._write_callback(field)
return
Modified: trunk/giscanner/transformer.py
==============================================================================
--- trunk/giscanner/transformer.py (original)
+++ trunk/giscanner/transformer.py Sat Oct 11 18:33:43 2008
@@ -126,8 +126,8 @@
raise NotImplementedError(filename)
for include in parser.get_includes():
self.register_include(include)
- nsname = parser.get_namespace_name()
- for node in parser.get_nodes():
+ nsname = parser.get_namespace().name
+ for node in parser.get_namespace().nodes:
if isinstance(node, Alias):
self._names.aliases[node.name] = (nsname, node)
elif isinstance(node, (GLibBoxed, Interface, Class)):
Modified: trunk/giscanner/xmlwriter.py
==============================================================================
--- trunk/giscanner/xmlwriter.py (original)
+++ trunk/giscanner/xmlwriter.py Sat Oct 11 18:33:43 2008
@@ -40,9 +40,12 @@
return -1
attr_length = 0
for attr, value in attributes:
+ # FIXME: actually, if we have attributes with None as value this
+ # should be considered a bug and raise an error. We are just
+ # ignoring them here while we fix GIRParser to create the right
+ # ast with the correct attributes.
if value is None:
- raise ValueError(
- "value for attribute %r cannot be None" % (attr, ))
+ continue
attr_length += 2 + len(attr) + len(quoteattr(value))
return attr_length + indent + self._indent
@@ -56,11 +59,14 @@
first = True
attr_value = ''
for attr, value in attributes:
+ # FIXME: actually, if we have attributes with None as value this
+ # should be considered a bug and raise an error. We are just
+ # ignoring them here while we fix GIRParser to create the right
+ # ast with the correct attributes.
+ if value is None:
+ continue
if indent_len and not first:
attr_value += '\n%s' % (self._indent_char * indent_len)
- if value is None:
- raise ValueError(
- "value for attribute %r cannot be None" % (attr, ))
attr_value += ' %s=%s' % (attr, quoteattr(value))
if first:
first = False
Modified: trunk/tools/g-ir-scanner
==============================================================================
--- trunk/tools/g-ir-scanner (original)
+++ trunk/tools/g-ir-scanner Sat Oct 11 18:33:43 2008
@@ -104,22 +104,31 @@
raise SystemExit('ERROR: %s' % (msg, ))
def typelib_xml_strip(path):
+ from giscanner.girparser import GIRParser
+ from giscanner.girwriter import GIRWriter
from giscanner.girparser import C_NS
c_ns_key = '{%s}' % (C_NS, )
- from xml.etree.cElementTree import parse
- doc = parse(open(path))
+ parser = GIRParser(path, initial_parse=False)
+ doc = parser.get_doc()
for node in doc.getiterator():
for attrib in list(node.attrib):
if attrib.startswith(c_ns_key):
del node.attrib[attrib]
- doc.write(sys.stdout)
+ parser.parse()
+ writer = GIRWriter(parser.get_namespace(),
+ parser.get_shared_libraries(),
+ parser.get_includes())
+ sys.stdout.write(writer.get_xml())
return 0
def inject(path, additions, outpath):
+ from giscanner.girparser import GIRParser
+ from giscanner.girwriter import GIRWriter
from xml.etree.cElementTree import parse
- doc = parse(open(path))
- root = doc.getroot()
+
+ parser = GIRParser(path, initial_parse=False)
+ root = parser.get_doc().getroot()
injectDoc = parse(open(additions))
for node in injectDoc.getroot():
injectPath = node.attrib['path']
@@ -128,8 +137,12 @@
raise ValueError("Couldn't find path %r" % (injectPath, ))
for child in node:
target.append(child)
+ parser.parse()
+ writer = GIRWriter(parser.get_namespace(),
+ parser.get_shared_libraries(),
+ parser.get_includes())
outf = open(outpath, 'w')
- doc.write(outf)
+ outf.write(writer.get_xml())
outf.close()
return 0
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]