summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMatthias Klumpp <matthias@tenstral.net>2024-07-09 00:12:55 +0200
committerMatthias Klumpp <matthias@tenstral.net>2024-07-09 00:12:55 +0200
commit366b64a24b9db63616500a8942c33b0ebb579ce9 (patch)
treed140e031951664adf7774c50a0d934573a1caee3 /tools
parentfbaae9a860b466b241b1e475aa37f8633d8a89d8 (diff)
Adjust build to work with Python 3 and modern toolingHEADmaster
Diffstat (limited to 'tools')
-rwxr-xr-xtools/doc-generator.py83
-rw-r--r--tools/specparser.py79
-rw-r--r--tools/xincludator.py9
3 files changed, 85 insertions, 86 deletions
diff --git a/tools/doc-generator.py b/tools/doc-generator.py
index 95a8011..f713664 100755
--- a/tools/doc-generator.py
+++ b/tools/doc-generator.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# doc-generator.py
#
-# Generates HTML documentation from the parsed spec using Cheetah templates.
+# Generates HTML documentation from the parsed spec
#
# Copyright (C) 2009 Collabora Ltd.
#
@@ -27,12 +27,13 @@ import sys
import os
import os.path
import shutil
+import itertools
try:
- from Cheetah.Template import Template
-except ImportError, e:
- print >> sys.stderr, e
- print >> sys.stderr, "Install `python-cheetah'?"
+ from jinja2 import Template
+except ImportError as e:
+ print(e, file=sys.stderr)
+ print("Install `jinja2'?", file=sys.stderr)
sys.exit(-1)
import specparser
@@ -67,54 +68,58 @@ def load_template(filename):
file = open(os.path.join(template_path, filename))
template_def = file.read()
file.close()
- except IOError, e:
- print >> sys.stderr, "Could not load template file `%s'" % filename
- print >> sys.stderr, e
+ except IOError as e:
+ print("Could not load template file `%s'" % filename, file=sys.stderr)
+ print(e, file=sys.stderr)
sys.exit(-1)
return template_def
+def render_template(name, context, target=None):
+ if target is None:
+ target = name
+ template_def = load_template(name)
+ t = Template(template_def).render(context)
+ with open(os.path.join(output_path, target), 'w') as out:
+ out.write(t)
+
spec = specparser.parse(spec_file, namespace, allow_externals=allow_externals)
# write out HTML files for each of the interfaces
-# Not using render_template here to avoid recompiling it n times.
-namespace = { 'spec': spec }
-template_def = load_template('interface.html')
-t = Template(template_def, namespaces = [namespace])
-for interface in spec.interfaces:
- namespace['interface'] = interface
+all_values = list(spec.everything.values()) + list(spec.errors.values()) + list(spec.types.values())
- # open the output file
- out = open(os.path.join(output_path, '%s.html'
- % interface.name_for_bindings), 'w')
- print >> out, unicode(t).encode('utf-8')
- out.close()
+star = [ (item.short_name, item) for item in all_values ]
+star.sort(key = lambda t: t[0].title())
+groups = [ (l, list(g)) for l, g in (itertools.groupby(star, key = lambda t: t[0][0].upper())) ]
+letters = set(map(lambda t: t[0], groups))
+all_letters = list(map(chr, range(ord('A'), ord('Z')+1)))
-def render_template(name, namespaces, target=None):
- if target is None:
- target = name
+context = { 'spec': spec, 'star': star, 'groups': groups,
+ 'letters': letters, 'all_letters': all_letters }
+render_template('fullindex.html', context)
- namespace = { 'spec': spec }
- template_def = load_template(name)
- t = Template(template_def, namespaces=namespaces)
- out = open(os.path.join(output_path, target), 'w')
- print >> out, unicode(t).encode('utf-8')
- out.close()
+context = { 'spec': spec, 'name': project, 'all_values': all_values }
+render_template('devhelp.devhelp2', context, target=('%s.devhelp2' % project))
-namespaces = { 'spec': spec }
+# Not using render_template here to avoid recompiling it n times.
+context = { 'spec': spec }
+template_def = load_template('interface.html')
+t = Template(template_def)
+for interface in spec.interfaces:
+ context['interface'] = interface
+ # open the output file
+ with open(os.path.join(output_path, '%s.html'
+ % interface.name_for_bindings), 'w') as out:
+ out.write(t.render(context))
+context = { 'spec': spec }
if len(spec.generic_types) > 0:
- render_template('generic-types.html', namespaces)
+ render_template('generic-types.html', context)
if len(spec.errors) > 0:
- render_template('errors.html', namespaces)
-render_template('interfaces.html', namespaces)
-render_template('fullindex.html', namespaces)
-
-dh_namespaces = { 'spec': spec, 'name': project }
-render_template('devhelp.devhelp2', dh_namespaces,
- target=('%s.devhelp2' % project))
+ render_template('errors.html', context)
+render_template('interfaces.html', context)
# write out the TOC last, because this is the file used as the target in the
# Makefile.
-render_template('index.html', namespaces)
+render_template('index.html', context)
diff --git a/tools/specparser.py b/tools/specparser.py
index 29ee0b5..472d098 100644
--- a/tools/specparser.py
+++ b/tools/specparser.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python3
#
# specparser.py
#
@@ -24,6 +25,7 @@
import sys
import xml.dom.minidom
+import functools
import xincludator
@@ -51,14 +53,14 @@ class Xzibit(Exception):
self.child = child
def __str__(self):
- print """
+ print ("""
Nested <%s>s are forbidden.
Parent:
%s...
Child:
%s...
""" % (self.parent.nodeName, self.parent.toxml()[:100],
- self.child.toxml()[:100])
+ self.child.toxml()[:100]))
def getText(dom):
try:
@@ -70,17 +72,17 @@ def getText(dom):
return ''
def getChildrenByName(dom, namespace, name):
- return filter(lambda n: n.nodeType == n.ELEMENT_NODE and \
+ return list(filter(lambda n: n.nodeType == n.ELEMENT_NODE and \
n.namespaceURI == namespace and \
n.localName == name,
- dom.childNodes)
+ dom.childNodes))
def getChildrenByNameAndAttribute(dom, namespace, name, attribute, value):
- return filter(lambda n: n.nodeType == n.ELEMENT_NODE and \
+ return list(filter(lambda n: n.nodeType == n.ELEMENT_NODE and \
n.namespaceURI == namespace and \
n.localName == name and \
n.getAttribute(attribute) == value,
- dom.childNodes)
+ dom.childNodes))
def getOnlyChildByName(dom, namespace, name):
kids = getChildrenByName(dom, namespace, name)
@@ -228,7 +230,7 @@ class Base(object):
self._convert_to_html(node)
- return node.toxml().encode('ascii', 'xmlcharrefreplace')
+ return node.toxml()
def get_added(self):
return self._get_generic_with_ver(self.added, 'added',
@@ -264,7 +266,7 @@ class Base(object):
self._convert_to_html(node)
- return node.toxml().encode('ascii', 'xmlcharrefreplace')
+ return node.toxml()
def _convert_to_html(self, node):
spec = self.get_spec()
@@ -342,10 +344,10 @@ class Base(object):
try:
e = spec.errors[error_ns + getText(n)]
except KeyError:
- print >> sys.stderr, """
+ print("""
WARNING: Error '%s' not known in error namespace '%s'
(<tp:error-ref> in %s)
- """.strip() % (getText(n), error_ns[:-1], self)
+ """.strip() % (getText(n), error_ns[:-1], self), file=sys.stderr)
continue
n.tagName = 'a'
@@ -359,10 +361,10 @@ WARNING: Error '%s' not known in error namespace '%s'
try:
o = spec.lookup(key, namespace=root_namespace)
except KeyError:
- print >> sys.stderr, """
+ print("""
WARNING: Key '%s' not known in namespace '%s'
(<tp:member-ref> in %s)
- """.strip() % (key, root_namespace, self)
+ """.strip() % (key, root_namespace, self), file=sys.stderr)
continue
n.tagName = 'a'
@@ -382,10 +384,10 @@ WARNING: Key '%s' not known in namespace '%s'
try:
o = spec.lookup(key, namespace=namespace)
except KeyError:
- print >> sys.stderr, """
+ print("""
WARNING: Key '%s' not known in namespace '%s'
(<tp:dbus-ref> in %s)
- """.strip() % (key, namespace, self)
+ """.strip() % (key, namespace, self), file=sys.stderr)
continue
n.tagName = 'a'
@@ -415,10 +417,10 @@ WARNING: Key '%s' not known in namespace '%s'
except KeyError:
o = spec.lookup(key, None)
except KeyError:
- print >> sys.stderr, """
+ print("""
WARNING: Key '%s' not known in namespace '%s'
(<tp:dbus-ref> in %s)
- """.strip() % (key, namespace, self)
+ """.strip() % (key, namespace, self), file=sys.stderr)
continue
n.tagName = 'a'
@@ -498,10 +500,10 @@ class PossibleError(Base):
return spec.errors[self.name]
except KeyError:
if not spec.allow_externals:
- print >> sys.stderr, """
+ print("""
WARNING: Error not known: '%s'
(<tp:possible-error> in %s)
- """.strip() % (self.name, self.parent)
+ """.strip() % (self.name, self.parent), file=sys.stderr)
return External(self.name)
@@ -528,8 +530,8 @@ class Method(DBusConstruct):
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)
+ self.in_args = list(filter(lambda a: a.direction == Arg.DIRECTION_IN, args))
+ self.out_args = list(filter(lambda a: a.direction == Arg.DIRECTION_OUT, args))
for arg in args:
if arg.direction == Arg.DIRECTION_IN or \
@@ -637,10 +639,11 @@ class HasEmitsChangedAnnotation(object):
try:
return self.__MAPPING[emits_changed]
except KeyError:
- print >> sys.stderr, """
+ print("""
WARNING: <annotation name='%s'/> has unknown value '%s'
(in %s)
- """.strip() % (self.__ANNOTATION, emits_changed, self)
+ """.strip() % (self.__ANNOTATION, emits_changed, self),
+ file=sys.stderr)
return self.EMITS_CHANGED_UNKNOWN;
class Property(DBusConstruct, Typed, HasEmitsChangedAnnotation):
@@ -662,8 +665,6 @@ class Property(DBusConstruct, Typed, HasEmitsChangedAnnotation):
else:
raise UnknownAccess("Unknown access '%s' on %s" % (access, self))
- self.is_optional = (getAnnotationByName(dom, 'org.mpris.MediaPlayer2.property.optional') == 'true')
-
is_cp = dom.getAttributeNS(XMLNS_TP, 'is-connection-parameter')
self.is_connection_parameter = is_cp != ''
@@ -705,20 +706,15 @@ class Property(DBusConstruct, Typed, HasEmitsChangedAnnotation):
return ', '.join(descriptions)
- def get_optional(self):
- if self.is_optional:
- return '<div class="annotation optional">This property is optional. Clients should handle its absence gracefully.</div>'
- else:
- return ''
-
class AwkwardTelepathyProperty(Typed):
def __init__(self, parent, namespace, dom):
Typed.__init__(self, parent, namespace, dom)
- print >> sys.stderr, """
+ print("""
WARNING: Old-style Telepathy properties are deprecated!
(<tp:property> in %s)
- """.strip() % (parent)
+ """.strip() % (parent),
+ file=sys.stderr)
def get_type_name(self):
return 'Telepathy Property'
@@ -869,10 +865,10 @@ class Interface(Base, HasEmitsChangedAnnotation):
return spec.lookup(r)
except KeyError:
if not spec.allow_externals:
- print >> sys.stderr, """
+ print("""
WARNING: Interface not known: '%s'
(<tp:requires> in %s)
- """.strip() % (r, self)
+ """.strip() % (r, self), file=sys.stderr)
return External(r)
@@ -920,10 +916,11 @@ WARNING: Interface not known: '%s'
]
if unexpected:
- print >> sys.stderr, """
+ print("""
WARNING: Unknown element(s): %s
(in interface '%s')
- """.strip() % (', '.join([x.tagName for x in unexpected]), self.name)
+ """.strip() % (', '.join([x.tagName for x in unexpected]), self.name),
+ file=sys.stderr)
class Error(Base):
def get_url(self):
@@ -1295,7 +1292,7 @@ class Spec(SectionBase):
key=lambda e: e.name)
# build a list of generic types
- self.generic_types = reduce (lambda a, b: a + b,
+ self.generic_types = functools.reduce (lambda a, b: a + b,
map(lambda l: parse_types(self, l),
dom.getElementsByTagNameNS(XMLNS_TP, 'generic-types')),
[])
@@ -1341,12 +1338,12 @@ class Spec(SectionBase):
except IndexError:
self.version = None
- self.copyrights = map(getText,
- getChildrenByName(node, XMLNS_TP, 'copyright'))
+ self.copyrights = list(map(getText,
+ getChildrenByName(node, XMLNS_TP, 'copyright')))
try:
license = getChildrenByName(node, XMLNS_TP, 'license')[0]
- self.license = map(getText, license.getElementsByTagName('p'))
+ self.license = list(map(getText, license.getElementsByTagName('p')))
except IndexError:
self.license = []
@@ -1393,7 +1390,7 @@ def build_dict(parent, type_, namespace, nodes):
return dict(build_tuple(n) for n in nodes)
def build_list(parent, type_, namespace, nodes):
- return map(lambda node: type_(parent, namespace, node), nodes)
+ return list(map(lambda node: type_(parent, namespace, node), nodes))
def parse_types(parent, dom, namespace = None):
"""Parse all of the types of type nodes mentioned in 't' from the node
diff --git a/tools/xincludator.py b/tools/xincludator.py
index 63e106a..9fcbc03 100644
--- a/tools/xincludator.py
+++ b/tools/xincludator.py
@@ -1,17 +1,14 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
-from sys import argv, stdout, stderr
-import codecs, locale
+from sys import argv, stdout
import os
import xml.dom.minidom
-stdout = codecs.getwriter('utf-8')(stdout)
-
NS_XI = 'http://www.w3.org/2001/XInclude'
def xincludate(dom, base, dropns = []):
remove_attrs = []
- for i in xrange(dom.documentElement.attributes.length):
+ for i in range(dom.documentElement.attributes.length):
attr = dom.documentElement.attributes.item(i)
if attr.prefix == 'xmlns':
if attr.localName in dropns: