[Telepathy-commits] [telepathy-spec/master] More work on parsing bits and pieces
Davyd Madeley
davyd at madeley.id.au
Mon Mar 23 12:29:16 PDT 2009
---
tools/specparser.py | 127 +++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 104 insertions(+), 23 deletions(-)
diff --git a/tools/specparser.py b/tools/specparser.py
index 8322d9f..0d6f539 100644
--- a/tools/specparser.py
+++ b/tools/specparser.py
@@ -19,34 +19,77 @@ class base (object):
Don't instantiate this class directly.
"""
- def __init__ (self, namespace, dom):
+ def __init__ (self, parent, namespace, dom):
name = dom.getAttribute ('name')
self.name = '.'.join (
filter (lambda n: n is not None,
[namespace, name.replace (' ', '')])
)
-
+
+ self.parent = parent
+
+ def get_interface (self):
+ return self.parent.get_interface ()
+
def __repr__ (self):
return '%s(%s)' % (self.__class__.__name__, self.name)
-class Method (base): pass
+class Method (base):
+ def __init__ (self, parent, namespace, dom):
+ super (Method, self).__init__ (parent, namespace, dom)
+
+ args = map (lambda n: Arg (self, None, n),
+ dom.getElementsByTagName ('arg'))
+
+ # separate arguments as input and output arguments
+ self.in_args = filter (lambda a: a.direction == Arg.DIRECTION_IN, args)
+ self.out_args = filter (lambda a: a.direction == Arg.DIRECTION_OUT, args)
class Property (base): pass
-class Signal (base): pass
+class Arg (base):
+ DIRECTION_IN, DIRECTION_OUT = range (2)
+
+ def __init__ (self, parent, namespace, dom):
+ super (Arg, self).__init__ (parent, namespace, dom)
+
+ type_ = dom.getAttributeNS (XMLNS_TP, 'type')
+ self.type = lookup_type (type_)
+
+ self.dbus_type = dom.getAttribute ('type')
+
+ direction = dom.getAttribute ('direction')
+ if direction == 'in':
+ self.direction = self.DIRECTION_IN
+ elif direction == 'out' or direction == '':
+ self.direction = self.DIRECTION_OUT
+ else:
+ class UnknownDirection (Exception): pass
+ raise UnknownDirection ("Unknown direction `%s' on %s" % (
+ direction, self.parent))
+
+ def __repr__ (self):
+ return '%s(%s:%s)' % (self.__class__.__name__, self.name, self.dbus_type)
+
+class Signal (base):
+ def __init__ (self, parent, namespace, dom):
+ super (Signal, self).__init__ (parent, namespace, dom)
+
+ self.args = map (lambda n: Arg (self, None, n),
+ dom.getElementsByTagName ('arg'))
class Interface (base):
- def __init__ (self, namespace, dom):
- super (Interface, self).__init__ (namespace, dom)
+ def __init__ (self, parent, namespace, dom):
+ super (Interface, self).__init__ (parent, namespace, dom)
- # build a dictionary of methods in this spec
- self.methods = build_dict (Method, self.name,
+ # build a dictionary of methods in this interface
+ self.methods = build_dict (self, Method, self.name,
dom.getElementsByTagName ('method'))
- # build a dictionary of properties in this spec
- self.properties = build_dict (Property, self.name,
+ # build a dictionary of properties in this interface
+ self.properties = build_dict (self, Property, self.name,
dom.getElementsByTagName ('property'))
- # build a dictionary of signals in this spec
- self.signals = build_dict (Signal, self.name,
+ # build a dictionary of signals in this interface
+ self.signals = build_dict (self, Signal, self.name,
dom.getElementsByTagName ('signal'))
# print '-'*78
@@ -54,6 +97,9 @@ class Interface (base):
# print self.properties
# print self.signals
+ def get_interface (self):
+ return self
+
class Error (base): pass
class DBusType (base):
@@ -67,7 +113,25 @@ class SimpleType (DBusType): pass
class Mapping (DBusType): pass
-def build_dict (type_, namespace, nodes):
+class Struct (DBusType): pass
+
+class Enum (DBusType): pass
+
+class Flags (DBusType): pass
+
+def lookup_type (type_):
+ if type_.endswith ('[]'):
+ type_ = type_[:-2]
+
+ if type_ == '': return None
+ elif type_ in types:
+ return types[type_]
+
+ class UnknownType (Exception): pass
+
+ raise UnknownType ("Type `%s' is unknown" % type_)
+
+def build_dict (parent, type_, namespace, nodes):
"""Build a dictionary of D-Bus names to Python objects representing that
name using the XML node for that item in the spec.
@@ -78,27 +142,44 @@ def build_dict (type_, namespace, nodes):
"""
def build_tuple (node):
- o = type_ (namespace, node)
+ o = type_ (parent, namespace, node)
return (o.name, o)
return dict (build_tuple (n) for n in nodes)
+def parse_types (parent, dom, d = None):
+ """Parse all of the types of type nodes mentioned in 't' from the node
+ 'dom' and insert them into the dictionary 'd'.
+ """
+ t = [
+ (SimpleType, 'simple-type'),
+ (Enum, 'enum'),
+ (Flags, 'flags'),
+ (Mapping, 'mapping'),
+ (Struct, 'struct'),
+ ]
+
+ if d is None: d = {}
+
+ for (type_, tagname) in t:
+ d.update (build_dict (parent, type_, None,
+ dom.getElementsByTagNameNS (XMLNS_TP, tagname)))
+
+ return d
+
def parse (filename):
dom = xml.dom.minidom.parse (filename)
xincludator.xincludate (dom, filename)
# build a dictionary of errors in this spec
errorsnode = dom.getElementsByTagNameNS (XMLNS_TP, 'errors')[0]
- errors.update (build_dict (Error, errorsnode.getAttribute ('namespace'),
- errorsnode.getElementsByTagNameNS (XMLNS_TP, 'error')))
- # build a dictionary of types in this spec
- typesnode = dom.getElementsByTagNameNS (XMLNS_TP, 'generic-types')[0]
- types.update (build_dict (SimpleType, None,
- typesnode.getElementsByTagNameNS (XMLNS_TP, 'simple-type')))
- types.update (build_dict (Mapping, None,
- typesnode.getElementsByTagNameNS (XMLNS_TP, 'mapping')))
+ errors.update (build_dict (None, Error,
+ errorsnode.getAttribute ('namespace'),
+ errorsnode.getElementsByTagNameNS (XMLNS_TP, 'error')))
+ # build a dictionary of ALL types in this spec
+ parse_types (None, dom, types)
# build a dictionary of interfaces in this spec
- interfaces = build_dict (Interface, None,
+ interfaces = build_dict (None, Interface, None,
dom.getElementsByTagName ('interface'))
return interfaces
--
1.5.6.5
More information about the telepathy-commits
mailing list