summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.co.uk>2012-07-02 15:37:05 +0200
committerXavier Claessens <xavier.claessens@collabora.co.uk>2012-07-03 12:09:56 +0200
commit4b7a97be0f8250af48c5b9f97cace813bc64c0f8 (patch)
treed438c36ea84e7b08d2d1c4abf0b197f1b4c81275 /tools
parentb1046b3ee4cdd00323a4267a994dc67865a170b0 (diff)
Update tools/ copy from telepathy-glib
This avoid single include from generated code
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile.am89
-rw-r--r--[-rwxr-xr-x]tools/c-constants-gen.py82
-rw-r--r--tools/check-c-style.sh7
-rw-r--r--tools/check-coding-style.mk2
-rwxr-xr-xtools/doc-generator.py104
-rw-r--r--tools/git-which-branch.sh25
-rw-r--r--[-rwxr-xr-x]tools/glib-client-gen.py315
-rw-r--r--[-rwxr-xr-x]tools/glib-client-marshaller-gen.py3
-rw-r--r--tools/glib-errors-check-gen.py58
-rw-r--r--tools/glib-errors-str-gen.py83
-rw-r--r--[-rwxr-xr-x]tools/glib-ginterface-gen.py206
-rw-r--r--[-rwxr-xr-x]tools/glib-gtypes-generator.py119
-rw-r--r--[-rwxr-xr-x]tools/glib-interfaces-gen.py102
-rwxr-xr-xtools/glib-signals-marshal-gen.py55
-rw-r--r--tools/gobject-foo.py90
-rw-r--r--tools/identity.xsl7
-rw-r--r--[-rwxr-xr-x]tools/libglibcodegen.py0
-rw-r--r--[-rwxr-xr-x]tools/libtpcodegen.py14
-rwxr-xr-xtools/log-strip.py35
-rw-r--r--tools/make-version-script.py208
-rw-r--r--tools/manager-file.py187
-rw-r--r--tools/shave.mk1
-rw-r--r--tools/specparser.py885
-rwxr-xr-xtools/telepathy-glib-env9
-rw-r--r--tools/telepathy-glib-env.in9
-rw-r--r--tools/telepathy-glib.supp390
-rw-r--r--tools/telepathy.am16
-rw-r--r--tools/valgrind.mk2
-rwxr-xr-x[-rw-r--r--]tools/with-session-bus.sh12
-rw-r--r--[-rwxr-xr-x]tools/xincludator.py0
30 files changed, 1688 insertions, 1427 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am
index ee31d17..761ee03 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,51 +1,78 @@
+abs_top_builddir = @abs_top_builddir@
+
+noinst_SCRIPTS = telepathy-glib-env
+
+telepathy-glib-env: telepathy-glib-env.in Makefile
+ sed -e 's![@]abs_top_builddir[@]!$(abs_top_builddir)!' $< > $@
+ chmod +x $@
+
+if ENABLE_INSTALLED_TESTS
+toolsdir = @tpglibtestsdir@/tools
+tools_SCRIPTS = \
+ with-session-bus.sh \
+ test-wrapper.sh \
+ libglibcodegen.py \
+ libtpcodegen.py \
+ $(NULL)
+endif
+
EXTRA_DIST = \
c-constants-gen.py \
check-coding-style.mk \
check-c-style.sh \
check-misc.sh \
check-whitespace.sh \
- doc-generator.py \
doc-generator.xsl \
+ flymake.mk \
+ git-which-branch.sh \
glib-client-gen.py \
glib-client-marshaller-gen.py \
+ glib-errors-check-gen.py \
+ glib-errors-str-gen.py \
glib-ginterface-gen.py \
glib-gtypes-generator.py \
glib-interfaces-gen.py \
- glib-signals-marshal-gen.py \
- identity.xsl \
+ gobject-foo.py \
lcov.am \
- libglibcodegen.py \
libtpcodegen.py \
- log-strip.py \
+ libglibcodegen.py \
make-release-mail.py \
- specparser.py \
+ make-version-script.py \
+ manager-file.py \
+ shave.mk \
telepathy.am \
+ telepathy-glib.supp \
+ telepathy-glib-env.in \
test-wrapper.sh \
- valgrind.mk \
with-session-bus.sh \
xincludator.py
-CLEANFILES = *.pyc *.pyo
-
-#
-# FIXME: The following stuff break makedist
-#
-#all: $(EXTRA_DIST)
-
-#libglibcodegen.py: libtpcodegen.py
-# test -e $<
-# $(AM_V_GEN)touch $@
-
-#glib-ginterface-gen.py glib-gtypes-generator.py glib-interfaces-gen.py \
-#glib-signals-marshal-gen.py c-constants-gen.py: %: libglibcodegen.py
-# test -e $<
-# $(AM_V_GEN)touch $@
-
-#TELEPATHY_GLIB_SRCDIR = $(top_srcdir)/../telepathy-glib
-#maintainer-update-from-telepathy-glib:
-# set -e && cd $(srcdir) && \
-# for x in $(EXTRA_DIST); do \
-# if test -f $(TELEPATHY_GLIB_SRCDIR)/tools/$$x; then \
-# cp $(TELEPATHY_GLIB_SRCDIR)/tools/$$x $$x; \
-# fi; \
-# done
+CLEANFILES = libtpcodegen.pyc libtpcodegen.pyo libglibcodegen.pyc libglibcodegen.pyo $(noinst_SCRIPTS)
+
+all: $(EXTRA_DIST)
+
+libglibcodegen.py: libtpcodegen.py
+ $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@
+c-constants-gen.py: libglibcodegen.py
+ $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@
+glib-client-marshaller-gen.py: libglibcodegen.py
+ $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@
+glib-errors-enum-body-gen.py: libglibcodegen.py
+ $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@
+glib-errors-enum-header-gen.py: libglibcodegen.py
+ $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@
+glib-ginterface-gen.py: libglibcodegen.py
+ $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@
+glib-gtypes-generator.py: libglibcodegen.py
+ $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@
+glib-interfaces-gen.py: libglibcodegen.py
+ $(AM_V_GEN)test -e ${srcdir}/$@ && touch ${srcdir}/$@
+
+TELEPATHY_SPEC_SRCDIR = $(top_srcdir)/../telepathy-spec
+maintainer-update-from-telepathy-spec:
+ set -e && cd $(srcdir) && \
+ for x in $(EXTRA_DIST); do \
+ if test -f $(TELEPATHY_SPEC_SRCDIR)/tools/$$x; then \
+ cp $(TELEPATHY_SPEC_SRCDIR)/tools/$$x $$x; \
+ fi; \
+ done
diff --git a/tools/c-constants-gen.py b/tools/c-constants-gen.py
index 8969ffd..c7a93d3 100755..100644
--- a/tools/c-constants-gen.py
+++ b/tools/c-constants-gen.py
@@ -3,21 +3,32 @@
from sys import argv, stdout, stderr
import xml.dom.minidom
+from libtpcodegen import file_set_contents
from libglibcodegen import NS_TP, get_docstring, \
get_descendant_text, get_by_path
class Generator(object):
- def __init__(self, prefix, dom):
+ def __init__(self, prefix, dom, output_base):
self.prefix = prefix + '_'
self.spec = get_by_path(dom, "spec")[0]
+ self.output_base = output_base
+ self.__header = []
+ self.__docs = []
+
def __call__(self):
self.do_header()
self.do_body()
self.do_footer()
+ file_set_contents(self.output_base + '.h', ''.join(self.__header))
+ file_set_contents(self.output_base + '-gtk-doc.h', ''.join(self.__docs))
+
def write(self, code):
- stdout.write(code.encode('utf-8'))
+ self.__header.append(code.encode('utf-8'))
+
+ def d(self, code):
+ self.__docs.append(code.encode('utf-8'))
# Header
def do_header(self):
@@ -54,25 +65,26 @@ extern "C" {
value_prefix = flags.getAttribute('singular') or \
flags.getAttribute('value-prefix') or \
flags.getAttribute('name')
- self.write("""\
+ self.d("""\
/**
- *
-%s:
+ * %s:
""" % (self.prefix + name).replace('_', ''))
for flag in get_by_path(flags, 'flag'):
self.do_gtkdoc(flag, value_prefix)
- self.write(' *\n')
+ self.d(' *\n')
docstrings = get_by_path(flags, 'docstring')
if docstrings:
- self.write("""\
+ self.d("""\
* <![CDATA[%s]]>
*
""" % get_descendant_text(docstrings).replace('\n', ' '))
- self.write("""\
+ self.d("""\
* Bitfield/set of flags generated from the Telepathy specification.
*/
-typedef enum {
""")
+
+ self.write("typedef enum /*< flags >*/ {\n")
+
for flag in get_by_path(flags, 'flag'):
self.do_val(flag, value_prefix)
self.write("""\
@@ -87,40 +99,56 @@ typedef enum {
enum.getAttribute('name')
name_plural = enum.getAttribute('plural') or \
enum.getAttribute('name') + 's'
- self.write("""\
+ self.d("""\
/**
- *
-%s:
+ * %s:
""" % (self.prefix + name).replace('_', ''))
vals = get_by_path(enum, 'enumvalue')
for val in vals:
self.do_gtkdoc(val, value_prefix)
- self.write(' *\n')
+ self.d(' *\n')
docstrings = get_by_path(enum, 'docstring')
if docstrings:
- self.write("""\
+ self.d("""\
* <![CDATA[%s]]>
*
""" % get_descendant_text(docstrings).replace('\n', ' '))
- self.write("""\
+ self.d("""\
* Bitfield/set of flags generated from the Telepathy specification.
*/
-typedef enum {
""")
+
+ self.write("typedef enum {\n")
+
for val in vals:
self.do_val(val, value_prefix)
- self.write("""\
-} %(mixed-name)s;
+ self.write("} %s;\n" % (self.prefix + name).replace('_', ''))
+ self.d("""\
/**
- * NUM_%(upper-plural)s:
+ * %(upper-prefix)sNUM_%(upper-plural)s:
*
* 1 higher than the highest valid value of #%(mixed-name)s.
*/
-#define NUM_%(upper-plural)s (%(last-val)s+1)
+
+/**
+ * NUM_%(upper-prefix)s%(upper-plural)s: (skip)
+ *
+ * 1 higher than the highest valid value of #%(mixed-name)s.
+ * In new code, use %(upper-prefix)sNUM_%(upper-plural)s instead.
+ */
+""" % {'mixed-name' : (self.prefix + name).replace('_', ''),
+ 'upper-prefix' : self.prefix.upper(),
+ 'upper-plural' : name_plural.upper(),
+ 'last-val' : vals[-1].getAttribute('value')})
+
+ self.write("""\
+#define %(upper-prefix)sNUM_%(upper-plural)s (%(last-val)s+1)
+#define NUM_%(upper-prefix)s%(upper-plural)s %(upper-prefix)sNUM_%(upper-plural)s
""" % {'mixed-name' : (self.prefix + name).replace('_', ''),
- 'upper-plural' : (self.prefix + name_plural).upper(),
+ 'upper-prefix' : self.prefix.upper(),
+ 'upper-plural' : name_plural.upper(),
'last-val' : vals[-1].getAttribute('value')})
def do_val(self, val, value_prefix):
@@ -133,13 +161,13 @@ typedef enum {
self.write(' %s = %s,\n' % (use_name, val.getAttribute('value')))
def do_gtkdoc(self, node, value_prefix):
- self.write(' * @')
- self.write((self.prefix + value_prefix + '_' +
+ self.d(' * @')
+ self.d((self.prefix + value_prefix + '_' +
node.getAttribute('suffix')).upper())
- self.write(': <![CDATA[')
+ self.d(': <![CDATA[')
docstring = get_by_path(node, 'docstring')
- self.write(get_descendant_text(docstring).replace('\n', ' '))
- self.write(']]>\n')
+ self.d(get_descendant_text(docstring).replace('\n', ' '))
+ self.d(']]>\n')
# Footer
def do_footer(self):
@@ -151,4 +179,4 @@ typedef enum {
if __name__ == '__main__':
argv = argv[1:]
- Generator(argv[0], xml.dom.minidom.parse(argv[1]))()
+ Generator(argv[0], xml.dom.minidom.parse(argv[1]), argv[2])()
diff --git a/tools/check-c-style.sh b/tools/check-c-style.sh
index 4330b14..5583420 100644
--- a/tools/check-c-style.sh
+++ b/tools/check-c-style.sh
@@ -3,13 +3,6 @@ fail=0
( . "${tools_dir}"/check-misc.sh ) || fail=$?
-if grep -n '^ *GError *\*[[:alpha:]_][[:alnum:]_]* *;' "$@"
-then
- echo "^^^ The above files contain uninitialized GError*s - they should be"
- echo " initialized to NULL"
- fail=1
-fi
-
# The first regex finds function calls like foo() (as opposed to foo ()).
# It attempts to ignore string constants (may cause false negatives).
# The second and third ignore block comments (gtkdoc uses foo() as markup).
diff --git a/tools/check-coding-style.mk b/tools/check-coding-style.mk
index 1c0a60f..f3f74fa 100644
--- a/tools/check-coding-style.mk
+++ b/tools/check-coding-style.mk
@@ -10,7 +10,7 @@ check-coding-style:
sh $(top_srcdir)/tools/check-c-style.sh \
$(addprefix $(srcdir)/,$(check_c_sources)) || fail=1; \
fi;\
- if test yes = "$(ENABLE_CODING_STYLE_CHECKS)"; then \
+ if test yes = "$(enable_fatal_warnings)"; then \
exit "$$fail";\
else \
exit 0;\
diff --git a/tools/doc-generator.py b/tools/doc-generator.py
deleted file mode 100755
index 5fc19ce..0000000
--- a/tools/doc-generator.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python
-#
-# doc-generator.py
-#
-# Generates HTML documentation from the parsed spec using Cheetah templates.
-#
-# Copyright (C) 2009 Collabora Ltd.
-#
-# This library is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or (at
-# your option) any later version.
-#
-# This library is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
-# for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this library; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# Authors: Davyd Madeley <davyd.madeley@collabora.co.uk>
-#
-
-import sys
-import os
-import os.path
-import shutil
-
-try:
- from Cheetah.Template import Template
-except ImportError, e:
- print >> sys.stderr, e
- print >> sys.stderr, "Install `python-cheetah'?"
- sys.exit(-1)
-
-import specparser
-
-program, spec_file, output_path, project, namespace = sys.argv
-
-template_path = os.path.join(os.path.dirname(program), '../doc/templates')
-
-# make the output path
-try:
- os.mkdir(output_path)
-except OSError:
- pass
-# copy in the CSS
-shutil.copy(os.path.join(template_path, 'style.css'), output_path)
-
-def load_template(filename):
- try:
- 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
- sys.exit(-1)
-
- return template_def
-
-spec = specparser.parse(spec_file, namespace)
-
-# write out HTML files for each of the interfaces
-
-# Not using render_template here to avoid recompiling it n times.
-namespace = {}
-template_def = load_template('interface.html')
-t = Template(template_def, namespaces = [namespace])
-for interface in spec.interfaces:
- namespace['interface'] = interface
-
- # open the output file
- out = open(os.path.join(output_path, '%s.html' % interface.name), 'w')
- print >> out, unicode(t).encode('utf-8')
- out.close()
-
-def render_template(name, namespaces, target=None):
- if target is None:
- target = name
-
- 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()
-
-namespaces = { 'spec': spec }
-
-render_template('generic-types.html', namespaces)
-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))
-
-# write out the TOC last, because this is the file used as the target in the
-# Makefile.
-render_template('index.html', namespaces)
diff --git a/tools/git-which-branch.sh b/tools/git-which-branch.sh
new file mode 100644
index 0000000..b96b5d5
--- /dev/null
+++ b/tools/git-which-branch.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+# git-which-branch.sh - output the name of the current git branch
+#
+# The canonical location of this program is the telepathy-spec tools/
+# directory, please synchronize any changes with that copy.
+#
+# Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved.
+
+default="$1"
+if { ref="`git symbolic-ref HEAD 2>/dev/null`"; }; then
+ echo ${ref#refs/heads/}
+ exit 0
+fi
+
+if test -n "$default"; then
+ echo "$default" >/dev/null
+ exit 0
+fi
+
+echo "no git branch found" >&2
+exit 1
diff --git a/tools/glib-client-gen.py b/tools/glib-client-gen.py
index 6988596..6b2b97f 100755..100644
--- a/tools/glib-client-gen.py
+++ b/tools/glib-client-gen.py
@@ -27,8 +27,9 @@ import os.path
import xml.dom.minidom
from getopt import gnu_getopt
+from libtpcodegen import file_set_contents
from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \
- get_docstring, xml_escape
+ get_docstring, xml_escape, get_deprecated
NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
@@ -39,6 +40,7 @@ class Generator(object):
self.dom = dom
self.__header = []
self.__body = []
+ self.__docs = []
self.prefix_lc = prefix.lower()
self.prefix_uc = prefix.upper()
@@ -55,9 +57,21 @@ class Generator(object):
% opts.get('--subclass', 'TpProxy'))
if self.proxy_arg == 'void *':
self.proxy_arg = 'gpointer '
- self.generate_reentrant = ('--generate-reentrant' in opts or
- '--deprecate-reentrant' in opts)
+
+ self.reentrant_symbols = set()
+ try:
+ filename = opts['--generate-reentrant']
+ with open(filename, 'r') as f:
+ for line in f.readlines():
+ self.reentrant_symbols.add(line.strip())
+ except KeyError:
+ pass
+
self.deprecate_reentrant = opts.get('--deprecate-reentrant', None)
+ self.deprecation_attribute = opts.get('--deprecation-attribute',
+ 'G_GNUC_DEPRECATED')
+
+ self.guard = opts.get('--guard', None)
def h(self, s):
if isinstance(s, unicode):
@@ -69,6 +83,11 @@ class Generator(object):
s = s.encode('utf-8')
self.__body.append(s)
+ def d(self, s):
+ if isinstance(s, unicode):
+ s = s.encode('utf-8')
+ self.__docs.append(s)
+
def get_iface_quark(self):
assert self.iface_dbus is not None
assert self.iface_uc is not None
@@ -121,25 +140,31 @@ class Generator(object):
# guint arg_handle, gboolean arg_suppress_handler,
# gpointer user_data, GObject *weak_object);
- self.b('/**')
- self.b(' * %s:' % callback_name)
- self.b(' * @proxy: The proxy on which %s_%s_connect_to_%s ()'
+ self.d('/**')
+ self.d(' * %s:' % callback_name)
+ self.d(' * @proxy: The proxy on which %s_%s_connect_to_%s ()'
% (self.prefix_lc, iface_lc, member_lc))
- self.b(' * was called')
+ self.d(' * was called')
for arg in args:
name, info, tp_type, elt = arg
ctype, gtype, marshaller, pointer = info
- self.b(' * @%s: %s' % (name,
- xml_escape(get_docstring(elt) or '(Undocumented)')))
+ docs = get_docstring(elt) or '(Undocumented)'
+
+ if ctype == 'guint ' and tp_type != '':
+ docs += ' (#%s)' % ('Tp' + tp_type.replace('_', ''))
- self.b(' * @user_data: User-supplied data')
- self.b(' * @weak_object: User-supplied weakly referenced object')
- self.b(' *')
- self.b(' * Represents the signature of a callback for the signal %s.'
+ self.d(' * @%s: %s' % (name, xml_escape(docs)))
+
+ self.d(' * @user_data: User-supplied data')
+ self.d(' * @weak_object: User-supplied weakly referenced object')
+ self.d(' *')
+ self.d(' * Represents the signature of a callback for the signal %s.'
% member)
- self.b(' */')
+ self.d(' */')
+ self.d('')
+
self.h('typedef void (*%s) (%sproxy,'
% (callback_name, self.proxy_cls))
@@ -288,31 +313,33 @@ class Generator(object):
# emitted the 'invalidated' signal, or because the weakly referenced
# object has gone away.
- self.b('/**')
- self.b(' * %s_%s_connect_to_%s:'
+ self.d('/**')
+ self.d(' * %s_%s_connect_to_%s:'
% (self.prefix_lc, iface_lc, member_lc))
- self.b(' * @proxy: %s' % self.proxy_doc)
- self.b(' * @callback: Callback to be called when the signal is')
- self.b(' * received')
- self.b(' * @user_data: User-supplied data for the callback')
- self.b(' * @destroy: Destructor for the user-supplied data, which')
- self.b(' * will be called when this signal is disconnected, or')
- self.b(' * before this function returns %NULL')
- self.b(' * @weak_object: A #GObject which will be weakly referenced; ')
- self.b(' * if it is destroyed, this callback will automatically be')
- self.b(' * disconnected')
- self.b(' * @error: If not %NULL, used to raise an error if %NULL is')
- self.b(' * returned')
- self.b(' *')
- self.b(' * Connect a handler to the signal %s.' % member)
- self.b(' *')
- self.b(' * %s' % xml_escape(get_docstring(signal) or '(Undocumented)'))
- self.b(' *')
- self.b(' * Returns: a #TpProxySignalConnection containing all of the')
- self.b(' * above, which can be used to disconnect the signal; or')
- self.b(' * %NULL if the proxy does not have the desired interface')
- self.b(' * or has become invalid.')
- self.b(' */')
+ self.d(' * @proxy: %s' % self.proxy_doc)
+ self.d(' * @callback: Callback to be called when the signal is')
+ self.d(' * received')
+ self.d(' * @user_data: User-supplied data for the callback')
+ self.d(' * @destroy: Destructor for the user-supplied data, which')
+ self.d(' * will be called when this signal is disconnected, or')
+ self.d(' * before this function returns %NULL')
+ self.d(' * @weak_object: A #GObject which will be weakly referenced; ')
+ self.d(' * if it is destroyed, this callback will automatically be')
+ self.d(' * disconnected')
+ self.d(' * @error: If not %NULL, used to raise an error if %NULL is')
+ self.d(' * returned')
+ self.d(' *')
+ self.d(' * Connect a handler to the signal %s.' % member)
+ self.d(' *')
+ self.d(' * %s' % xml_escape(get_docstring(signal) or '(Undocumented)'))
+ self.d(' *')
+ self.d(' * Returns: a #TpProxySignalConnection containing all of the')
+ self.d(' * above, which can be used to disconnect the signal; or')
+ self.d(' * %NULL if the proxy does not have the desired interface')
+ self.d(' * or has become invalid.')
+ self.d(' */')
+ self.d('')
+
self.h('TpProxySignalConnection *%s_%s_connect_to_%s (%sproxy,'
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
self.h(' %s callback,' % callback_name)
@@ -320,6 +347,7 @@ class Generator(object):
self.h(' GDestroyNotify destroy,')
self.h(' GObject *weak_object,')
self.h(' GError **error);')
+ self.h('')
self.b('TpProxySignalConnection *')
self.b('%s_%s_connect_to_%s (%sproxy,'
@@ -359,8 +387,6 @@ class Generator(object):
self.b('}')
self.b('')
- self.h('')
-
def do_method(self, iface, method):
iface_lc = iface.lower()
@@ -412,27 +438,40 @@ class Generator(object):
# gpointer user_data,
# GObject *weak_object);
- self.b('/**')
- self.b(' * %s_%s_callback_for_%s:'
+ self.d('/**')
+ self.d(' * %s_%s_callback_for_%s:'
% (self.prefix_lc, iface_lc, member_lc))
- self.b(' * @proxy: the proxy on which the call was made')
+ self.d(' * @proxy: the proxy on which the call was made')
for arg in out_args:
name, info, tp_type, elt = arg
ctype, gtype, marshaller, pointer = info
- self.b(' * @%s: Used to return an \'out\' argument if @error is '
+ docs = xml_escape(get_docstring(elt) or '(Undocumented)')
+
+ if ctype == 'guint ' and tp_type != '':
+ docs += ' (#%s)' % ('Tp' + tp_type.replace('_', ''))
+
+ self.d(' * @%s: Used to return an \'out\' argument if @error is '
'%%NULL: %s'
- % (name, xml_escape(get_docstring(elt) or '(Undocumented)')))
+ % (name, docs))
- self.b(' * @error: %NULL on success, or an error on failure')
- self.b(' * @user_data: user-supplied data')
- self.b(' * @weak_object: user-supplied object')
- self.b(' *')
- self.b(' * Signature of the callback called when a %s method call'
+ self.d(' * @error: %NULL on success, or an error on failure')
+ self.d(' * @user_data: user-supplied data')
+ self.d(' * @weak_object: user-supplied object')
+ self.d(' *')
+ self.d(' * Signature of the callback called when a %s method call'
% member)
- self.b(' * succeeds or fails.')
- self.b(' */')
+ self.d(' * succeeds or fails.')
+
+ deprecated = method.getElementsByTagName('tp:deprecated')
+ if deprecated:
+ d = deprecated[0]
+ self.d(' *')
+ self.d(' * Deprecated: %s' % xml_escape(get_deprecated(d)))
+
+ self.d(' */')
+ self.d('')
callback_name = '%s_%s_callback_for_%s' % (self.prefix_lc, iface_lc,
member_lc)
@@ -657,42 +696,56 @@ class Generator(object):
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
self.h(' gint timeout_ms,')
- self.b('/**')
- self.b(' * %s_%s_call_%s:'
+ self.d('/**')
+ self.d(' * %s_%s_call_%s:'
% (self.prefix_lc, iface_lc, member_lc))
- self.b(' * @proxy: the #TpProxy')
- self.b(' * @timeout_ms: the timeout in milliseconds, or -1 to use the')
- self.b(' * default')
+ self.d(' * @proxy: the #TpProxy')
+ self.d(' * @timeout_ms: the timeout in milliseconds, or -1 to use the')
+ self.d(' * default')
for arg in in_args:
name, info, tp_type, elt = arg
ctype, gtype, marshaller, pointer = info
- self.b(' * @%s: Used to pass an \'in\' argument: %s'
- % (name, xml_escape(get_docstring(elt) or '(Undocumented)')))
+ docs = xml_escape(get_docstring(elt) or '(Undocumented)')
+
+ if ctype == 'guint ' and tp_type != '':
+ docs += ' (#%s)' % ('Tp' + tp_type.replace('_', ''))
+
+ self.d(' * @%s: Used to pass an \'in\' argument: %s'
+ % (name, docs))
+
+ self.d(' * @callback: called when the method call succeeds or fails;')
+ self.d(' * may be %NULL to make a "fire and forget" call with no ')
+ self.d(' * reply tracking')
+ self.d(' * @user_data: user-supplied data passed to the callback;')
+ self.d(' * must be %NULL if @callback is %NULL')
+ self.d(' * @destroy: called with the user_data as argument, after the')
+ self.d(' * call has succeeded, failed or been cancelled;')
+ self.d(' * must be %NULL if @callback is %NULL')
+ self.d(' * @weak_object: If not %NULL, a #GObject which will be ')
+ self.d(' * weakly referenced; if it is destroyed, this call ')
+ self.d(' * will automatically be cancelled. Must be %NULL if ')
+ self.d(' * @callback is %NULL')
+ self.d(' *')
+ self.d(' * Start a %s method call.' % member)
+ self.d(' *')
+ self.d(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)'))
+ self.d(' *')
+ self.d(' * Returns: a #TpProxyPendingCall representing the call in')
+ self.d(' * progress. It is borrowed from the object, and will become')
+ self.d(' * invalid when the callback is called, the call is')
+ self.d(' * cancelled or the #TpProxy becomes invalid.')
+
+ deprecated = method.getElementsByTagName('tp:deprecated')
+ if deprecated:
+ d = deprecated[0]
+ self.d(' *')
+ self.d(' * Deprecated: %s' % xml_escape(get_deprecated(d)))
+
+ self.d(' */')
+ self.d('')
- self.b(' * @callback: called when the method call succeeds or fails;')
- self.b(' * may be %NULL to make a "fire and forget" call with no ')
- self.b(' * reply tracking')
- self.b(' * @user_data: user-supplied data passed to the callback;')
- self.b(' * must be %NULL if @callback is %NULL')
- self.b(' * @destroy: called with the user_data as argument, after the')
- self.b(' * call has succeeded, failed or been cancelled;')
- self.b(' * must be %NULL if @callback is %NULL')
- self.b(' * @weak_object: If not %NULL, a #GObject which will be ')
- self.b(' * weakly referenced; if it is destroyed, this call ')
- self.b(' * will automatically be cancelled. Must be %NULL if ')
- self.b(' * @callback is %NULL')
- self.b(' *')
- self.b(' * Start a %s method call.' % member)
- self.b(' *')
- self.b(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)'))
- self.b(' *')
- self.b(' * Returns: a #TpProxyPendingCall representing the call in')
- self.b(' * progress. It is borrowed from the object, and will become')
- self.b(' * invalid when the callback is called, the call is')
- self.b(' * cancelled or the #TpProxy becomes invalid.')
- self.b(' */')
self.b('TpProxyPendingCall *\n%s_%s_call_%s (%sproxy,'
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
self.b(' gint timeout_ms,')
@@ -804,11 +857,11 @@ class Generator(object):
self.b('}')
self.b('')
- if self.generate_reentrant:
- self.do_method_reentrant(method, iface_lc, member, member_lc,
- in_args, out_args, collect_callback)
+ self.do_method_reentrant(method, iface_lc, member, member_lc,
+ in_args, out_args, collect_callback)
# leave a gap for the end of the method
+ self.d('')
self.b('')
self.h('')
@@ -824,6 +877,10 @@ class Generator(object):
# GError **error,
# GMainLoop **loop);
+ run_method_name = '%s_%s_run_%s' % (self.prefix_lc, iface_lc, member_lc)
+ if run_method_name not in self.reentrant_symbols:
+ return
+
self.b('typedef struct {')
self.b(' GMainLoop *loop;')
self.b(' GError **error;')
@@ -901,50 +958,64 @@ class Generator(object):
if self.deprecate_reentrant:
self.h('#ifndef %s' % self.deprecate_reentrant)
- self.h('gboolean %s_%s_run_%s (%sproxy,'
- % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.h('gboolean %s (%sproxy,'
+ % (run_method_name, self.proxy_arg))
self.h(' gint timeout_ms,')
- self.b('/**')
- self.b(' * %s_%s_run_%s:' % (self.prefix_lc, iface_lc, member_lc))
- self.b(' * @proxy: %s' % self.proxy_doc)
- self.b(' * @timeout_ms: Timeout in milliseconds, or -1 for default')
+ self.d('/**')
+ self.d(' * %s:' % run_method_name)
+ self.d(' * @proxy: %s' % self.proxy_doc)
+ self.d(' * @timeout_ms: Timeout in milliseconds, or -1 for default')
for arg in in_args:
name, info, tp_type, elt = arg
ctype, gtype, marshaller, pointer = info
- self.b(' * @%s: Used to pass an \'in\' argument: %s'
- % (name, xml_escape(get_docstring(elt) or '(Undocumented)')))
+ docs = xml_escape(get_docstring(elt) or '(Undocumented)')
+
+ if ctype == 'guint ' and tp_type != '':
+ docs += ' (#%s)' % ('Tp' + tp_type.replace('_', ''))
+
+ self.d(' * @%s: Used to pass an \'in\' argument: %s'
+ % (name, docs))
for arg in out_args:
name, info, tp_type, elt = arg
ctype, gtype, marshaller, pointer = info
- self.b(' * @%s: Used to return an \'out\' argument if %%TRUE is '
+ self.d(' * @%s: Used to return an \'out\' argument if %%TRUE is '
'returned: %s'
% (name, xml_escape(get_docstring(elt) or '(Undocumented)')))
- self.b(' * @error: If not %NULL, used to return errors if %FALSE ')
- self.b(' * is returned')
- self.b(' * @loop: If not %NULL, set before re-entering ')
- self.b(' * the main loop, to point to a #GMainLoop ')
- self.b(' * which can be used to cancel this call with ')
- self.b(' * g_main_loop_quit(), causing a return of ')
- self.b(' * %FALSE with @error set to %TP_DBUS_ERROR_CANCELLED')
- self.b(' *')
- self.b(' * Call the method %s and run the main loop' % member)
- self.b(' * until it returns. Before calling this method, you must')
- self.b(' * add a reference to any borrowed objects you need to keep,')
- self.b(' * and generally ensure that everything is in a consistent')
- self.b(' * state.')
- self.b(' *')
- self.b(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)'))
- self.b(' *')
- self.b(' * Returns: TRUE on success, FALSE and sets @error on error')
- self.b(' */')
- self.b('gboolean\n%s_%s_run_%s (%sproxy,'
- % (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
+ self.d(' * @error: If not %NULL, used to return errors if %FALSE ')
+ self.d(' * is returned')
+ self.d(' * @loop: If not %NULL, set before re-entering ')
+ self.d(' * the main loop, to point to a #GMainLoop ')
+ self.d(' * which can be used to cancel this call with ')
+ self.d(' * g_main_loop_quit(), causing a return of ')
+ self.d(' * %FALSE with @error set to %TP_DBUS_ERROR_CANCELLED')
+ self.d(' *')
+ self.d(' * Call the method %s and run the main loop' % member)
+ self.d(' * until it returns. Before calling this method, you must')
+ self.d(' * add a reference to any borrowed objects you need to keep,')
+ self.d(' * and generally ensure that everything is in a consistent')
+ self.d(' * state.')
+ self.d(' *')
+ self.d(' * %s' % xml_escape(get_docstring(method) or '(Undocumented)'))
+ self.d(' *')
+ self.d(' * Returns: TRUE on success, FALSE and sets @error on error')
+
+ deprecated = method.getElementsByTagName('tp:deprecated')
+ if deprecated:
+ d = deprecated[0]
+ self.d(' *')
+ self.d(' * Deprecated: %s' % xml_escape(get_deprecated(d)))
+
+ self.d(' */')
+ self.d('')
+
+ self.b('gboolean\n%s (%sproxy,'
+ % (run_method_name, self.proxy_arg))
self.b(' gint timeout_ms,')
for arg in in_args:
@@ -966,7 +1037,7 @@ class Generator(object):
self.h(' GError **error,')
if self.deprecate_reentrant:
- self.h(' GMainLoop **loop) G_GNUC_DEPRECATED;')
+ self.h(' GMainLoop **loop) %s;' % self.deprecation_attribute)
self.h('#endif /* not %s */' % self.deprecate_reentrant)
else:
self.h(' GMainLoop **loop);')
@@ -1102,6 +1173,11 @@ class Generator(object):
def __call__(self):
+ if self.guard is not None:
+ self.h('#ifndef %s' % self.guard)
+ self.h('#define %s' % self.guard)
+ self.h('')
+
self.h('G_BEGIN_DECLS')
self.h('')
@@ -1160,9 +1236,13 @@ class Generator(object):
self.h('G_END_DECLS')
self.h('')
- open(self.basename + '.h', 'w').write('\n'.join(self.__header))
- open(self.basename + '-body.h', 'w').write('\n'.join(self.__body))
+ if self.guard is not None:
+ self.h('#endif /* defined (%s) */' % self.guard)
+ self.h('')
+ file_set_contents(self.basename + '.h', '\n'.join(self.__header))
+ file_set_contents(self.basename + '-body.h', '\n'.join(self.__body))
+ file_set_contents(self.basename + '-gtk-doc.h', '\n'.join(self.__docs))
def types_to_gtypes(types):
return [type_to_gtype(t)[1] for t in types]
@@ -1172,7 +1252,8 @@ if __name__ == '__main__':
options, argv = gnu_getopt(sys.argv[1:], '',
['group=', 'subclass=', 'subclass-assert=',
'iface-quark-prefix=', 'tp-proxy-api=',
- 'generate-reentrant', 'deprecate-reentrant='])
+ 'generate-reentrant=', 'deprecate-reentrant=',
+ 'deprecation-attribute=', 'guard='])
opts = {}
diff --git a/tools/glib-client-marshaller-gen.py b/tools/glib-client-marshaller-gen.py
index 5444725..cb27d63 100755..100644
--- a/tools/glib-client-marshaller-gen.py
+++ b/tools/glib-client-marshaller-gen.py
@@ -40,7 +40,8 @@ class Generator(object):
for marshaller in all:
rhs = self.marshallers[marshaller]
- print ' dbus_g_object_register_marshaller (%s,' % marshaller
+ print ' dbus_g_object_register_marshaller ('
+ print ' g_cclosure_marshal_generic,'
print ' G_TYPE_NONE, /* return */'
for type in rhs:
print ' G_TYPE_%s,' % type.replace('VOID', 'NONE')
diff --git a/tools/glib-errors-check-gen.py b/tools/glib-errors-check-gen.py
new file mode 100644
index 0000000..553fc9c
--- /dev/null
+++ b/tools/glib-errors-check-gen.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+
+import sys
+import xml.dom.minidom
+
+from libglibcodegen import NS_TP, get_docstring, get_descendant_text
+
+class Generator(object):
+ def __init__(self, dom):
+ self.dom = dom
+ self.errors = self.dom.getElementsByTagNameNS(NS_TP, 'errors')[0]
+
+ def __call__(self):
+
+ print '{'
+ print ' GEnumClass *klass;'
+ print ' GEnumValue *value_by_name;'
+ print ' GEnumValue *value_by_nick;'
+ print ''
+ print ' g_type_init ();'
+ print ' klass = g_type_class_ref (TP_TYPE_ERROR);'
+
+ for error in self.errors.getElementsByTagNameNS(NS_TP, 'error'):
+ ns = error.parentNode.getAttribute('namespace')
+ nick = error.getAttribute('name').replace(' ', '')
+ enum = ('TP_ERROR_' +
+ error.getAttribute('name').replace(' ', '_').replace('.', '_').upper())
+ s = ('TP_ERROR_STR_' +
+ error.getAttribute('name').replace(' ', '_').replace('.', '_').upper())
+
+ print ''
+ print ' /* %s.%s */' % (ns, nick)
+ print (' value_by_name = g_enum_get_value_by_name (klass, "%s");'
+ % enum)
+ print (' value_by_nick = g_enum_get_value_by_nick (klass, "%s");'
+ % nick)
+ print (' g_assert (value_by_name != NULL);')
+ print (' g_assert (value_by_nick != NULL);')
+ print (' g_assert_cmpint (value_by_name->value, ==, %s);'
+ % enum)
+ print (' g_assert_cmpint (value_by_nick->value, ==, %s);'
+ % enum)
+ print (' g_assert_cmpstr (value_by_name->value_name, ==, "%s");'
+ % enum)
+ print (' g_assert_cmpstr (value_by_nick->value_name, ==, "%s");'
+ % enum)
+ print (' g_assert_cmpstr (value_by_name->value_nick, ==, "%s");'
+ % nick)
+ print (' g_assert_cmpstr (value_by_nick->value_nick, ==, "%s");'
+ % nick)
+ print (' g_assert_cmpstr (%s, ==, TP_ERROR_PREFIX ".%s");'
+ % (s, nick))
+
+ print '}'
+
+if __name__ == '__main__':
+ argv = sys.argv[1:]
+ Generator(xml.dom.minidom.parse(argv[0]))()
diff --git a/tools/glib-errors-str-gen.py b/tools/glib-errors-str-gen.py
new file mode 100644
index 0000000..b2cf520
--- /dev/null
+++ b/tools/glib-errors-str-gen.py
@@ -0,0 +1,83 @@
+#!/usr/bin/python
+
+import sys
+import xml.dom.minidom
+
+from libtpcodegen import file_set_contents
+from libglibcodegen import NS_TP, get_docstring, xml_escape
+
+class Generator(object):
+ def __init__(self, dom, basename):
+ self.dom = dom
+ self.errors = self.dom.getElementsByTagNameNS(NS_TP, 'errors')[0]
+ self.basename = basename
+
+ self.__header = []
+ self.__body = []
+ self.__docs = []
+
+ def h(self, s):
+ if isinstance(s, unicode):
+ s = s.encode('utf-8')
+ self.__header.append(s)
+
+ def b(self, s):
+ if isinstance(s, unicode):
+ s = s.encode('utf-8')
+ self.__body.append(s)
+
+ def d(self, s):
+ if isinstance(s, unicode):
+ s = s.encode('utf-8')
+ self.__docs.append(s)
+
+ def __call__(self):
+ errors = self.errors.getElementsByTagNameNS(NS_TP, 'error')
+
+ self.b('#include <telepathy-glib/errors.h>')
+ self.b('')
+ self.b('const gchar *')
+ self.b('tp_error_get_dbus_name (TpError error)')
+ self.b('{')
+ self.b(' switch (error)')
+ self.b(' {')
+
+ for error in errors:
+ ns = error.parentNode.getAttribute('namespace')
+ nick = error.getAttribute('name').replace(' ', '')
+ uc_nick = error.getAttribute('name').replace(' ', '_').replace('.', '_').upper()
+ name = 'TP_ERROR_STR_' + uc_nick
+ error_name = '%s.%s' % (ns, nick)
+
+ self.d('/**')
+ self.d(' * %s:' % name)
+ self.d(' *')
+ self.d(' * The D-Bus error name %s' % error_name)
+ self.d(' *')
+ self.d(' * %s' % xml_escape(get_docstring(error)))
+ self.d(' */')
+ self.d('')
+
+ self.h('#define %s "%s"' % (name, error_name))
+
+ self.b(' case TP_ERROR_%s:' % uc_nick)
+ self.b(' return %s;' % name)
+
+ self.b(' default:')
+ self.b(' g_return_val_if_reached (NULL);')
+ self.b(' }')
+ self.b('}')
+
+ # make both files end with a newline
+ self.h('')
+ self.b('')
+
+ file_set_contents(self.basename + '.h', '\n'.join(self.__header))
+ file_set_contents(self.basename + '.c', '\n'.join(self.__body))
+ file_set_contents(self.basename + '-gtk-doc.h', '\n'.join(self.__docs))
+
+if __name__ == '__main__':
+ argv = sys.argv[1:]
+ basename = argv[0]
+
+ Generator(xml.dom.minidom.parse(argv[1]), basename)()
diff --git a/tools/glib-ginterface-gen.py b/tools/glib-ginterface-gen.py
index 95c827c..7843977 100755..100644
--- a/tools/glib-ginterface-gen.py
+++ b/tools/glib-ginterface-gen.py
@@ -26,13 +26,23 @@ import sys
import os.path
import xml.dom.minidom
+from libtpcodegen import file_set_contents
from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \
- NS_TP, dbus_gutils_wincaps_to_uscore, \
- signal_to_marshal_name, method_to_glue_marshal_name
+ NS_TP, dbus_gutils_wincaps_to_uscore
NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
+def get_emits_changed(node):
+ try:
+ return [
+ annotation.getAttribute('value')
+ for annotation in node.getElementsByTagName('annotation')
+ if annotation.getAttribute('name') == 'org.freedesktop.DBus.Property.EmitsChangedSignal'
+ ][0]
+ except IndexError:
+ return None
+
class Generator(object):
def __init__(self, dom, prefix, basename, signal_marshal_prefix,
@@ -41,6 +51,7 @@ class Generator(object):
self.dom = dom
self.__header = []
self.__body = []
+ self.__docs = []
assert prefix.endswith('_')
assert not signal_marshal_prefix.endswith('_')
@@ -74,11 +85,20 @@ class Generator(object):
self.allow_havoc = allow_havoc
def h(self, s):
+ if isinstance(s, unicode):
+ s = s.encode('utf-8')
self.__header.append(s)
def b(self, s):
+ if isinstance(s, unicode):
+ s = s.encode('utf-8')
self.__body.append(s)
+ def d(self, s):
+ if isinstance(s, unicode):
+ s = s.encode('utf-8')
+ self.__docs.append(s)
+
def do_node(self, node):
node_name = node.getAttribute('name').replace('/', '')
node_name_mixed = self.node_name_mixed = node_name.replace('_', '')
@@ -98,6 +118,8 @@ class Generator(object):
if tmp and not self.allow_havoc:
raise AssertionError('%s is %s' % (self.iface_name, tmp))
+ iface_emits_changed = get_emits_changed(interface)
+
self.b('static const DBusGObjectInfo _%s%s_object_info;'
% (self.prefix_, node_name_lc))
self.b('')
@@ -158,54 +180,54 @@ class Generator(object):
self.b('}')
self.b('')
- self.h('/**')
- self.h(' * %s%s:' % (self.Prefix, node_name_mixed))
- self.h(' *')
- self.h(' * Dummy typedef representing any implementation of this '
+ self.d('/**')
+ self.d(' * %s%s:' % (self.Prefix, node_name_mixed))
+ self.d(' *')
+ self.d(' * Dummy typedef representing any implementation of this '
'interface.')
- self.h(' */')
+ self.d(' */')
+
self.h('typedef struct _%s%s %s%s;'
% (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed))
self.h('')
- self.h('/**')
- self.h(' * %s%sClass:' % (self.Prefix, node_name_mixed))
- self.h(' *')
- self.h(' * The class of %s%s.' % (self.Prefix, node_name_mixed))
+
+ self.d('/**')
+ self.d(' * %s%sClass:' % (self.Prefix, node_name_mixed))
+ self.d(' *')
+ self.d(' * The class of %s%s.' % (self.Prefix, node_name_mixed))
if methods:
- self.h(' *')
- self.h(' * In a full implementation of this interface (i.e. all')
- self.h(' * methods implemented), the interface initialization')
- self.h(' * function used in G_IMPLEMENT_INTERFACE() would')
- self.h(' * typically look like this:')
- self.h(' *')
- self.h(' * <programlisting>')
- self.h(' * static void')
- self.h(' * implement_%s (gpointer klass,' % self.node_name_lc)
- self.h(' * gpointer unused G_GNUC_UNUSED)')
- self.h(' * {')
- # "#" is special to gtkdoc under some circumstances; it appears
- # that escaping "##" as "#<!---->#" or "&#35;&#35;" doesn't work,
- # but adding an extra hash symbol does. Thanks, gtkdoc :-(
- self.h(' * #define IMPLEMENT(x) %s%s_implement_###x (\\'
+ self.d(' *')
+ self.d(' * In a full implementation of this interface (i.e. all')
+ self.d(' * methods implemented), the interface initialization')
+ self.d(' * function used in G_IMPLEMENT_INTERFACE() would')
+ self.d(' * typically look like this:')
+ self.d(' *')
+ self.d(' * <programlisting>')
+ self.d(' * static void')
+ self.d(' * implement_%s (gpointer klass,' % self.node_name_lc)
+ self.d(' * gpointer unused G_GNUC_UNUSED)')
+ self.d(' * {')
+ self.d(' * #define IMPLEMENT(x) %s%s_implement_&num;&num;x (\\'
% (self.prefix_, self.node_name_lc))
- self.h(' * klass, my_object_###x)')
+ self.d(' * klass, my_object_&num;&num;x)')
for method in methods:
class_member_name = method.getAttribute('tp:name-for-bindings')
class_member_name = class_member_name.lower()
- self.h(' * IMPLEMENT (%s);' % class_member_name)
+ self.d(' * IMPLEMENT (%s);' % class_member_name)
- self.h(' * #undef IMPLEMENT')
- self.h(' * }')
- self.h(' * </programlisting>')
+ self.d(' * #undef IMPLEMENT')
+ self.d(' * }')
+ self.d(' * </programlisting>')
else:
- self.h(' * This interface has no D-Bus methods, so an')
- self.h(' * implementation can typically pass %NULL to')
- self.h(' * G_IMPLEMENT_INTERFACE() as the interface')
- self.h(' * initialization function.')
+ self.d(' * This interface has no D-Bus methods, so an')
+ self.d(' * implementation can typically pass %NULL to')
+ self.d(' * G_IMPLEMENT_INTERFACE() as the interface')
+ self.d(' * initialization function.')
- self.h(' */')
+ self.d(' */')
+ self.d('')
self.h('typedef struct _%s%sClass %s%sClass;'
% (self.Prefix, node_name_mixed, self.Prefix, node_name_mixed))
@@ -260,6 +282,16 @@ class Generator(object):
flags = ('TP_DBUS_PROPERTIES_MIXIN_FLAG_READ | '
'TP_DBUS_PROPERTIES_MIXIN_FLAG_WRITE')
+ prop_emits_changed = get_emits_changed(m)
+
+ if prop_emits_changed is None:
+ prop_emits_changed = iface_emits_changed
+
+ if prop_emits_changed == 'true':
+ flags += ' | TP_DBUS_PROPERTIES_MIXIN_FLAG_EMITS_CHANGED'
+ elif prop_emits_changed == 'invalidates':
+ flags += ' | TP_DBUS_PROPERTIES_MIXIN_FLAG_EMITS_INVALIDATED'
+
self.b(' { 0, %s, "%s", 0, NULL, NULL }, /* %s */'
% (flags, m.getAttribute('type'), m.getAttribute('name')))
@@ -389,8 +421,7 @@ class Generator(object):
'not match' % (method.getAttribute('name'), lc_name))
lc_name = lc_name.lower()
- marshaller = method_to_glue_marshal_name(method,
- self.signal_marshal_prefix)
+ marshaller = 'g_cclosure_marshal_generic'
wrapper = self.prefix_ + self.node_name_lc + '_' + lc_name
self.b(" { (GCallback) %s, %s, %d }," % (wrapper, marshaller, offset))
@@ -477,18 +508,19 @@ class Generator(object):
else:
out_args.append(struct)
- # Implementation type declaration (in header, docs in body)
- self.b('/**')
- self.b(' * %s:' % impl_name)
- self.b(' * @self: The object implementing this interface')
+ # Implementation type declaration (in header, docs separated)
+ self.d('/**')
+ self.d(' * %s:' % impl_name)
+ self.d(' * @self: The object implementing this interface')
for (ctype, name) in in_args:
- self.b(' * @%s: %s (FIXME, generate documentation)'
+ self.d(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
- self.b(' * @context: Used to return values or throw an error')
- self.b(' *')
- self.b(' * The signature of an implementation of the D-Bus method')
- self.b(' * %s on interface %s.' % (dbus_method_name, self.iface_name))
- self.b(' */')
+ self.d(' * @context: Used to return values or throw an error')
+ self.d(' *')
+ self.d(' * The signature of an implementation of the D-Bus method')
+ self.d(' * %s on interface %s.' % (dbus_method_name, self.iface_name))
+ self.d(' */')
+
self.h('typedef void (*%s) (%s%s *self,'
% (impl_name, self.Prefix, self.node_name_mixed))
for (ctype, name) in in_args:
@@ -533,18 +565,19 @@ class Generator(object):
% (self.prefix_, self.node_name_lc, class_member_name,
self.Prefix, self.node_name_mixed, impl_name))
- self.b('/**')
- self.b(' * %s%s_implement_%s:'
+ self.d('/**')
+ self.d(' * %s%s_implement_%s:'
% (self.prefix_, self.node_name_lc, class_member_name))
- self.b(' * @klass: A class whose instances implement this interface')
- self.b(' * @impl: A callback used to implement the %s D-Bus method'
+ self.d(' * @klass: A class whose instances implement this interface')
+ self.d(' * @impl: A callback used to implement the %s D-Bus method'
% dbus_method_name)
- self.b(' *')
- self.b(' * Register an implementation for the %s method in the vtable'
+ self.d(' *')
+ self.d(' * Register an implementation for the %s method in the vtable'
% dbus_method_name)
- self.b(' * of an implementation of this interface. To be called from')
- self.b(' * the interface init function.')
- self.b(' */')
+ self.d(' * of an implementation of this interface. To be called from')
+ self.d(' * the interface init function.')
+ self.d(' */')
+
self.b('void')
self.b('%s%s_implement_%s (%s%sClass *klass, %s impl)'
% (self.prefix_, self.node_name_lc, class_member_name,
@@ -555,16 +588,18 @@ class Generator(object):
self.b('')
# Return convenience function (static inline, in header)
- self.h('/**')
- self.h(' * %s:' % ret_name)
- self.h(' * @context: The D-Bus method invocation context')
+ self.d('/**')
+ self.d(' * %s:' % ret_name)
+ self.d(' * @context: The D-Bus method invocation context')
for (ctype, name) in out_args:
- self.h(' * @%s: %s (FIXME, generate documentation)'
+ self.d(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
- self.h(' *')
- self.h(' * Return successfully by calling dbus_g_method_return().')
- self.h(' * This inline function exists only to provide type-safety.')
- self.h(' */')
+ self.d(' *')
+ self.d(' * Return successfully by calling dbus_g_method_return().')
+ self.d(' * This inline function exists only to provide type-safety.')
+ self.d(' */')
+ self.d('')
+
tmp = (['DBusGMethodInvocation *context'] +
[ctype + name for (ctype, name) in out_args])
self.h('static inline')
@@ -634,17 +669,17 @@ class Generator(object):
# FIXME: emit docs
- self.b('/**')
- self.b(' * %s:' % stub_name)
- self.b(' * @instance: The object implementing this interface')
+ self.d('/**')
+ self.d(' * %s:' % stub_name)
+ self.d(' * @instance: The object implementing this interface')
for (ctype, name, gtype) in args:
- self.b(' * @%s: %s (FIXME, generate documentation)'
+ self.d(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
- self.b(' *')
- self.b(' * Type-safe wrapper around g_signal_emit to emit the')
- self.b(' * %s signal on interface %s.'
+ self.d(' *')
+ self.d(' * Type-safe wrapper around g_signal_emit to emit the')
+ self.d(' * %s signal on interface %s.'
% (dbus_name, self.iface_name))
- self.b(' */')
+ self.d(' */')
self.b('void')
self.b(('%s (' % stub_name) + (',\n '.join(tmp)) + ')')
@@ -660,16 +695,20 @@ class Generator(object):
signal_name = dbus_gutils_wincaps_to_uscore(dbus_name).replace('_',
'-')
- in_base_init.append(' /**')
- in_base_init.append(' * %s%s::%s:'
+
+ self.d('/**')
+ self.d(' * %s%s::%s:'
% (self.Prefix, self.node_name_mixed, signal_name))
+ self.d(' * @self: an object')
for (ctype, name, gtype) in args:
- in_base_init.append(' * @%s: %s (FIXME, generate documentation)'
+ self.d(' * @%s: %s (FIXME, generate documentation)'
% (name, ctype))
- in_base_init.append(' *')
- in_base_init.append(' * The %s D-Bus signal is emitted whenever '
+ self.d(' *')
+ self.d(' * The %s D-Bus signal is emitted whenever '
'this GObject signal is.' % dbus_name)
- in_base_init.append(' */')
+ self.d(' */')
+ self.d('')
+
in_base_init.append(' %s_signals[%s] ='
% (self.node_name_lc, const_name))
in_base_init.append(' g_signal_new ("%s",' % signal_name)
@@ -677,8 +716,7 @@ class Generator(object):
in_base_init.append(' G_SIGNAL_RUN_LAST|G_SIGNAL_DETAILED,')
in_base_init.append(' 0,')
in_base_init.append(' NULL, NULL,')
- in_base_init.append(' %s,'
- % signal_to_marshal_name(signal, self.signal_marshal_prefix))
+ in_base_init.append(' g_cclosure_marshal_generic,')
in_base_init.append(' G_TYPE_NONE,')
tmp = ['%d' % len(args)] + [gtype for (ctype, name, gtype) in args]
in_base_init.append(' %s);' % ',\n '.join(tmp))
@@ -725,9 +763,9 @@ class Generator(object):
self.h('')
self.b('')
- open(self.basename + '.h', 'w').write('\n'.join(self.__header))
- open(self.basename + '.c', 'w').write('\n'.join(self.__body))
-
+ file_set_contents(self.basename + '.h', '\n'.join(self.__header))
+ file_set_contents(self.basename + '.c', '\n'.join(self.__body))
+ file_set_contents(self.basename + '-gtk-doc.h', '\n'.join(self.__docs))
def cmdline_error():
print """\
diff --git a/tools/glib-gtypes-generator.py b/tools/glib-gtypes-generator.py
index ebc2ad4..21dfc6a 100755..100644
--- a/tools/glib-gtypes-generator.py
+++ b/tools/glib-gtypes-generator.py
@@ -23,6 +23,7 @@
import sys
import xml.dom.minidom
+from libtpcodegen import file_set_contents
from libglibcodegen import escape_as_identifier, \
get_docstring, \
NS_TP, \
@@ -42,14 +43,16 @@ class GTypesGenerator(object):
self.PREFIX_ = self.Prefix.upper() + '_'
self.prefix_ = self.Prefix.lower() + '_'
- self.header = open(output + '.h', 'w')
- self.body = open(output + '-body.h', 'w')
+ self.header = []
+ self.body = []
+ self.docs = []
+ self.output = output
- for f in (self.header, self.body):
- f.write('/* Auto-generated, do not edit.\n *\n'
- ' * This file may be distributed under the same terms\n'
- ' * as the specification from which it was generated.\n'
- ' */\n\n')
+ for f in (self.header, self.body, self.docs):
+ f.append('/* Auto-generated, do not edit.\n *\n'
+ ' * This file may be distributed under the same terms\n'
+ ' * as the specification from which it was generated.\n'
+ ' */\n\n')
# keys are e.g. 'sv', values are the key escaped
self.need_mappings = {}
@@ -65,10 +68,13 @@ class GTypesGenerator(object):
self.need_other_arrays = {}
def h(self, code):
- self.header.write(code.encode("utf-8"))
+ self.header.append(code.encode("utf-8"))
def c(self, code):
- self.body.write(code.encode("utf-8"))
+ self.body.append(code.encode("utf-8"))
+
+ def d(self, code):
+ self.docs.append(code.encode('utf-8'))
def do_mapping_header(self, mapping):
members = mapping.getElementsByTagNameNS(NS_TP, 'member')
@@ -85,41 +91,41 @@ class GTypesGenerator(object):
docstring = get_docstring(mapping) or '(Undocumented)'
- self.h('/**\n * %s:\n *\n' % name)
- self.h(' * %s\n' % xml_escape(docstring))
- self.h(' *\n')
- self.h(' * This macro expands to a call to a function\n')
- self.h(' * that returns the #GType of a #GHashTable\n')
- self.h(' * appropriate for representing a D-Bus\n')
- self.h(' * dictionary of signature\n')
- self.h(' * <literal>a{%s}</literal>.\n' % impl_sig)
- self.h(' *\n')
+ self.d('/**\n * %s:\n *\n' % name.strip())
+ self.d(' * %s\n' % xml_escape(docstring))
+ self.d(' *\n')
+ self.d(' * This macro expands to a call to a function\n')
+ self.d(' * that returns the #GType of a #GHashTable\n')
+ self.d(' * appropriate for representing a D-Bus\n')
+ self.d(' * dictionary of signature\n')
+ self.d(' * <literal>a{%s}</literal>.\n' % impl_sig)
+ self.d(' *\n')
key, value = members
- self.h(' * Keys (D-Bus type <literal>%s</literal>,\n'
+ self.d(' * Keys (D-Bus type <literal>%s</literal>,\n'
% key.getAttribute('type'))
tp_type = key.getAttributeNS(NS_TP, 'type')
if tp_type:
- self.h(' * type <literal>%s</literal>,\n' % tp_type)
- self.h(' * named <literal>%s</literal>):\n'
+ self.d(' * type <literal>%s</literal>,\n' % tp_type)
+ self.d(' * named <literal>%s</literal>):\n'
% key.getAttribute('name'))
docstring = get_docstring(key) or '(Undocumented)'
- self.h(' * %s\n' % xml_escape(docstring))
- self.h(' *\n')
+ self.d(' * %s\n' % xml_escape(docstring))
+ self.d(' *\n')
- self.h(' * Values (D-Bus type <literal>%s</literal>,\n'
+ self.d(' * Values (D-Bus type <literal>%s</literal>,\n'
% value.getAttribute('type'))
tp_type = value.getAttributeNS(NS_TP, 'type')
if tp_type:
- self.h(' * type <literal>%s</literal>,\n' % tp_type)
- self.h(' * named <literal>%s</literal>):\n'
+ self.d(' * type <literal>%s</literal>,\n' % tp_type)
+ self.d(' * named <literal>%s</literal>):\n'
% value.getAttribute('name'))
docstring = get_docstring(value) or '(Undocumented)'
- self.h(' * %s\n' % xml_escape(docstring))
- self.h(' *\n')
+ self.d(' * %s\n' % xml_escape(docstring))
+ self.d(' *\n')
- self.h(' */\n')
+ self.d(' */\n')
self.h('#define %s (%s ())\n\n' % (name, impl))
self.need_mappings[impl_sig] = esc_impl_sig
@@ -130,11 +136,12 @@ class GTypesGenerator(object):
contents_sig = 'a{' + impl_sig + '}'
esc_contents_sig = escape_as_identifier(contents_sig)
impl = self.prefix_ + 'type_dbus_array_of_' + esc_contents_sig
- self.h('/**\n * %s:\n\n' % gtype_name)
- self.h(' * Expands to a call to a function\n')
- self.h(' * that returns the #GType of a #GPtrArray\n')
- self.h(' * of #%s.\n' % name)
- self.h(' */\n')
+ self.d('/**\n * %s:\n\n' % gtype_name)
+ self.d(' * Expands to a call to a function\n')
+ self.d(' * that returns the #GType of a #GPtrArray\n')
+ self.d(' * of #%s.\n' % name)
+ self.d(' */\n\n')
+
self.h('#define %s (%s ())\n\n' % (gtype_name, impl))
self.need_other_arrays[contents_sig] = esc_contents_sig
@@ -157,41 +164,43 @@ class GTypesGenerator(object):
docstring = '(Undocumented)'
else:
docstring = '(Undocumented)'
- self.h('/**\n * %s:\n\n' % name)
- self.h(' * %s\n' % xml_escape(docstring))
- self.h(' *\n')
- self.h(' * This macro expands to a call to a function\n')
- self.h(' * that returns the #GType of a #GValueArray\n')
- self.h(' * appropriate for representing a D-Bus struct\n')
- self.h(' * with signature <literal>(%s)</literal>.\n'
+ self.d('/**\n * %s:\n\n' % name)
+ self.d(' * %s\n' % xml_escape(docstring))
+ self.d(' *\n')
+ self.d(' * This macro expands to a call to a function\n')
+ self.d(' * that returns the #GType of a #GValueArray\n')
+ self.d(' * appropriate for representing a D-Bus struct\n')
+ self.d(' * with signature <literal>(%s)</literal>.\n'
% impl_sig)
- self.h(' *\n')
+ self.d(' *\n')
for i, member in enumerate(members):
- self.h(' * Member %d (D-Bus type '
+ self.d(' * Member %d (D-Bus type '
'<literal>%s</literal>,\n'
% (i, member.getAttribute('type')))
tp_type = member.getAttributeNS(NS_TP, 'type')
if tp_type:
- self.h(' * type <literal>%s</literal>,\n' % tp_type)
- self.h(' * named <literal>%s</literal>):\n'
+ self.d(' * type <literal>%s</literal>,\n' % tp_type)
+ self.d(' * named <literal>%s</literal>):\n'
% member.getAttribute('name'))
docstring = get_docstring(member) or '(Undocumented)'
- self.h(' * %s\n' % xml_escape(docstring))
- self.h(' *\n')
+ self.d(' * %s\n' % xml_escape(docstring))
+ self.d(' *\n')
+
+ self.d(' */\n\n')
- self.h(' */\n')
self.h('#define %s (%s ())\n\n' % (name, impl))
array_name = struct.getAttribute('array-name')
if array_name != '':
array_name = (self.PREFIX_ + 'ARRAY_TYPE_' + array_name.upper())
impl = self.prefix_ + 'type_dbus_array_' + esc_impl_sig
- self.h('/**\n * %s:\n\n' % array_name)
- self.h(' * Expands to a call to a function\n')
- self.h(' * that returns the #GType of a #GPtrArray\n')
- self.h(' * of #%s.\n' % name)
- self.h(' */\n')
+ self.d('/**\n * %s:\n\n' % array_name)
+ self.d(' * Expands to a call to a function\n')
+ self.d(' * that returns the #GType of a #GPtrArray\n')
+ self.d(' * of #%s.\n' % name)
+ self.d(' */\n\n')
+
self.h('#define %s (%s ())\n\n' % (array_name, impl))
self.need_struct_arrays[impl_sig] = esc_impl_sig
@@ -283,6 +292,10 @@ class GTypesGenerator(object):
self.c(' return t;\n')
self.c('}\n\n')
+ file_set_contents(self.output + '.h', ''.join(self.header))
+ file_set_contents(self.output + '-body.h', ''.join(self.body))
+ file_set_contents(self.output + '-gtk-doc.h', ''.join(self.docs))
+
if __name__ == '__main__':
argv = sys.argv[1:]
diff --git a/tools/glib-interfaces-gen.py b/tools/glib-interfaces-gen.py
index 9543968..410762c 100755..100644
--- a/tools/glib-interfaces-gen.py
+++ b/tools/glib-interfaces-gen.py
@@ -3,27 +3,44 @@
from sys import argv, stdout, stderr
import xml.dom.minidom
+from libtpcodegen import file_set_contents
from libglibcodegen import NS_TP, get_docstring, \
get_descendant_text, get_by_path
class Generator(object):
def __init__(self, prefix, implfile, declfile, dom):
self.prefix = prefix + '_'
- self.impls = open(implfile, 'w')
- self.decls = open(declfile, 'w')
+
+ assert declfile.endswith('.h')
+ docfile = declfile[:-2] + '-gtk-doc.h'
+
+ self.implfile = implfile
+ self.declfile = declfile
+ self.docfile = docfile
+
+ self.impls = []
+ self.decls = []
+ self.docs = []
self.spec = get_by_path(dom, "spec")[0]
def h(self, code):
- self.decls.write(code.encode('utf-8'))
+ self.decls.append(code.encode('utf-8'))
def c(self, code):
- self.impls.write(code.encode('utf-8'))
+ self.impls.append(code.encode('utf-8'))
+
+ def d(self, code):
+ self.docs.append(code.encode('utf-8'))
def __call__(self):
for f in self.h, self.c:
self.do_header(f)
self.do_body()
+ file_set_contents(self.implfile, ''.join(self.impls))
+ file_set_contents(self.declfile, ''.join(self.decls))
+ file_set_contents(self.docfile, ''.join(self.docs))
+
# Header
def do_header(self, f):
f('/* Generated from: ')
@@ -41,6 +58,7 @@ class Generator(object):
f("""
*/
+#include <glib.h>
""")
# Body
@@ -50,25 +68,37 @@ class Generator(object):
def do_iface(self, iface):
parent_name = get_by_path(iface, '../@name')
- self.h("""\
+ self.d("""\
/**
* %(IFACE_DEFINE)s:
*
* The interface name "%(name)s"
*/
+""" % {'IFACE_DEFINE' : (self.prefix + 'IFACE_' + \
+ parent_name).upper().replace('/', ''),
+ 'name' : iface.getAttribute('name')})
+
+ self.h("""
#define %(IFACE_DEFINE)s \\
"%(name)s"
""" % {'IFACE_DEFINE' : (self.prefix + 'IFACE_' + \
parent_name).upper().replace('/', ''),
'name' : iface.getAttribute('name')})
- self.h("""
+ self.d("""
/**
* %(IFACE_QUARK_DEFINE)s:
*
* Expands to a call to a function that returns a quark for the interface \
name "%(name)s"
*/
+""" % {'IFACE_QUARK_DEFINE' : (self.prefix + 'IFACE_QUARK_' + \
+ parent_name).upper().replace('/', ''),
+ 'iface_quark_func' : (self.prefix + 'iface_quark_' + \
+ parent_name).lower().replace('/', ''),
+ 'name' : iface.getAttribute('name')})
+
+ self.h("""
#define %(IFACE_QUARK_DEFINE)s \\
(%(iface_quark_func)s ())
@@ -99,12 +129,20 @@ GQuark
'name' : iface.getAttribute('name')})
for prop in iface.getElementsByTagNameNS(None, 'property'):
- self.decls.write("""
+ self.d("""
/**
* %(IFACE_PREFIX)s_%(PROP_UC)s:
*
* The fully-qualified property name "%(name)s.%(prop)s"
*/
+""" % {'IFACE_PREFIX' : (self.prefix + 'PROP_' + \
+ parent_name).upper().replace('/', ''),
+ 'PROP_UC': prop.getAttributeNS(NS_TP, "name-for-bindings").upper(),
+ 'name' : iface.getAttribute('name'),
+ 'prop' : prop.getAttribute('name'),
+ })
+
+ self.h("""
#define %(IFACE_PREFIX)s_%(PROP_UC)s \\
"%(name)s.%(prop)s"
""" % {'IFACE_PREFIX' : (self.prefix + 'PROP_' + \
@@ -114,6 +152,56 @@ GQuark
'prop' : prop.getAttribute('name'),
})
+
+ for prop in iface.getElementsByTagNameNS(NS_TP, 'contact-attribute'):
+ self.d("""
+/**
+ * %(TOKEN_PREFIX)s_%(TOKEN_UC)s:
+ *
+ * The fully-qualified contact attribute token name "%(name)s/%(prop)s"
+ */
+""" % {'TOKEN_PREFIX' : (self.prefix + 'TOKEN_' + \
+ parent_name).upper().replace('/', ''),
+ 'TOKEN_UC': prop.getAttributeNS(None, "name").upper().replace("-", "_").replace(".", "_"),
+ 'name' : iface.getAttribute('name'),
+ 'prop' : prop.getAttribute('name'),
+ })
+
+ self.h("""
+#define %(TOKEN_PREFIX)s_%(TOKEN_UC)s \\
+"%(name)s/%(prop)s"
+""" % {'TOKEN_PREFIX' : (self.prefix + 'TOKEN_' + \
+ parent_name).upper().replace('/', ''),
+ 'TOKEN_UC': prop.getAttributeNS(None, "name").upper().replace("-", "_").replace(".", "_"),
+ 'name' : iface.getAttribute('name'),
+ 'prop' : prop.getAttribute('name'),
+ })
+
+ for prop in iface.getElementsByTagNameNS(NS_TP, 'hct'):
+ if (prop.getAttribute('is-family') != "yes"):
+ self.d("""
+/**
+ * %(TOKEN_PREFIX)s_%(TOKEN_UC)s:
+ *
+ * The fully-qualified capability token name "%(name)s/%(prop)s"
+ */
+""" % {'TOKEN_PREFIX' : (self.prefix + 'TOKEN_' + \
+ parent_name).upper().replace('/', ''),
+ 'TOKEN_UC': prop.getAttributeNS(None, "name").upper().replace("-", "_").replace(".", "_"),
+ 'name' : iface.getAttribute('name'),
+ 'prop' : prop.getAttribute('name'),
+ })
+
+ self.h("""
+#define %(TOKEN_PREFIX)s_%(TOKEN_UC)s \\
+"%(name)s/%(prop)s"
+""" % {'TOKEN_PREFIX' : (self.prefix + 'TOKEN_' + \
+ parent_name).upper().replace('/', ''),
+ 'TOKEN_UC': prop.getAttributeNS(None, "name").upper().replace("-", "_").replace(".", "_"),
+ 'name' : iface.getAttribute('name'),
+ 'prop' : prop.getAttribute('name'),
+ })
+
if __name__ == '__main__':
argv = argv[1:]
Generator(argv[0], argv[1], argv[2], xml.dom.minidom.parse(argv[3]))()
diff --git a/tools/glib-signals-marshal-gen.py b/tools/glib-signals-marshal-gen.py
deleted file mode 100755
index 0d02c13..0000000
--- a/tools/glib-signals-marshal-gen.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/python
-
-import sys
-import xml.dom.minidom
-from string import ascii_letters, digits
-
-
-from libglibcodegen import signal_to_marshal_name, method_to_glue_marshal_name
-
-
-class Generator(object):
-
- def __init__(self, dom):
- self.dom = dom
- self.marshallers = {}
-
- def do_method(self, method):
- marshaller = method_to_glue_marshal_name(method, 'PREFIX')
-
- assert '__' in marshaller
- rhs = marshaller.split('__', 1)[1].split('_')
-
- self.marshallers[marshaller] = rhs
-
- def do_signal(self, signal):
- marshaller = signal_to_marshal_name(signal, 'PREFIX')
-
- assert '__' in marshaller
- rhs = marshaller.split('__', 1)[1].split('_')
-
- self.marshallers[marshaller] = rhs
-
- def __call__(self):
- methods = self.dom.getElementsByTagName('method')
-
- for method in methods:
- self.do_method(method)
-
- signals = self.dom.getElementsByTagName('signal')
-
- for signal in signals:
- self.do_signal(signal)
-
- all = self.marshallers.keys()
- all.sort()
- for marshaller in all:
- rhs = self.marshallers[marshaller]
- if not marshaller.startswith('g_cclosure'):
- print 'VOID:' + ','.join(rhs)
-
-if __name__ == '__main__':
- argv = sys.argv[1:]
- dom = xml.dom.minidom.parse(argv[0])
-
- Generator(dom)()
diff --git a/tools/gobject-foo.py b/tools/gobject-foo.py
new file mode 100644
index 0000000..002a290
--- /dev/null
+++ b/tools/gobject-foo.py
@@ -0,0 +1,90 @@
+#!/usr/bin/python
+
+# gobject-foo.py: generate standard GObject type macros etc.
+#
+# The master copy of this program is in the telepathy-glib repository -
+# please make any changes there.
+#
+# Copyright (C) 2007-2010 Collabora Ltd. <http://www.collabora.co.uk/>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+def gobject_header(head, tail, as_interface=False):
+ out = []
+ o = out.append
+
+ name = head + '_' + tail
+ MixedCase = name.replace('_', '')
+ lower_case = name.lower()
+ UPPER_CASE = name.upper()
+
+ gtype = head.upper() + '_TYPE_' + tail.upper()
+
+ o("typedef struct _%s %s;" % (MixedCase, MixedCase))
+
+ if as_interface:
+ o("typedef struct _%sInterface %sInterface;" % (MixedCase, MixedCase))
+ else:
+ o("typedef struct _%sClass %sClass;" % (MixedCase, MixedCase))
+ o("typedef struct _%sPrivate %sPrivate;" % (MixedCase, MixedCase))
+
+ o("")
+ o("GType %s_get_type (void);" % lower_case)
+ o("")
+
+ o("#define %s \\" % gtype)
+ o(" (%s_get_type ())" % lower_case)
+
+ o("#define %s(obj) \\" % UPPER_CASE)
+ o(" (G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, \\" % gtype)
+ o(" %s))" % MixedCase)
+
+ if not as_interface:
+ o("#define %s_CLASS(klass) \\" % UPPER_CASE)
+ o(" (G_TYPE_CHECK_CLASS_CAST ((klass), %s, \\" % gtype)
+ o(" %sClass))" % MixedCase)
+
+ o("#define %s_IS_%s(obj) \\" % (head.upper(), tail.upper()))
+ o(" (G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))" % gtype)
+
+ if as_interface:
+ o("#define %s_GET_IFACE(obj) \\" % UPPER_CASE)
+ o(" (G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, \\" % gtype)
+ o(" %sInterface))" % MixedCase)
+ else:
+ o("#define %s_IS_%s_CLASS(klass) \\" % (head.upper(), tail.upper()))
+ o(" (G_TYPE_CHECK_CLASS_TYPE ((klass), %s))" % gtype)
+
+ o("#define %s_GET_CLASS(obj) \\" % UPPER_CASE)
+ o(" (G_TYPE_INSTANCE_GET_CLASS ((obj), %s, \\" % gtype)
+ o(" %sClass))" % MixedCase)
+
+ return out
+
+if __name__ == '__main__':
+ import sys
+ from getopt import gnu_getopt
+
+ options, argv = gnu_getopt(sys.argv[1:], '', ['interface'])
+
+ as_interface = False
+
+ for opt, val in options:
+ if opt == '--interface':
+ as_interface = True
+
+ head, tail = argv
+
+ print '\n'.join(gobject_header(head, tail, as_interface=as_interface))
diff --git a/tools/identity.xsl b/tools/identity.xsl
deleted file mode 100644
index 6630f84..0000000
--- a/tools/identity.xsl
+++ /dev/null
@@ -1,7 +0,0 @@
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
- <xsl:template match="@*|node()">
- <xsl:copy>
- <xsl:apply-templates select="@*|node()"/>
- </xsl:copy>
- </xsl:template>
-</xsl:stylesheet>
diff --git a/tools/libglibcodegen.py b/tools/libglibcodegen.py
index 6a9d214..6a9d214 100755..100644
--- a/tools/libglibcodegen.py
+++ b/tools/libglibcodegen.py
diff --git a/tools/libtpcodegen.py b/tools/libtpcodegen.py
index 837ff2f..7e9eb9a 100755..100644
--- a/tools/libtpcodegen.py
+++ b/tools/libtpcodegen.py
@@ -20,7 +20,7 @@ please make any changes there.
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
+import os
from string import ascii_letters, digits
@@ -28,6 +28,18 @@ NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
_ASCII_ALNUM = ascii_letters + digits
+def file_set_contents(filename, contents):
+ try:
+ os.remove(filename)
+ except OSError:
+ pass
+ try:
+ os.remove(filename + '.tmp')
+ except OSError:
+ pass
+
+ open(filename + '.tmp', 'w').write(contents)
+ os.rename(filename + '.tmp', filename)
def cmp_by_name(node1, node2):
return cmp(node1.getAttributeNode("name").nodeValue,
diff --git a/tools/log-strip.py b/tools/log-strip.py
deleted file mode 100755
index 3c8ca93..0000000
--- a/tools/log-strip.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/python
-"""
-Strip varying data (PIDs, pointer values) from Gabble logs to make them
-easier to compare.
-"""
-
-from __future__ import with_statement
-
-import re
-import sys
-
-def sanitise(line):
- return (
- re.sub('^(\*\* )?\(telepathy-gabble:\d+\)', '',
- re.sub('\x1b\[0m', '',
- re.sub('^RECV \[\d+\]', 'RECV [???]',
- re.sub('0x[0-9A-Fa-f]{5,8}', '0x???????',
- re.sub("('?<[^ ]+ [^>]*id=)[\"'][^\"']+[\"']",
- lambda m: m.group(1) + '"?????"', line))))))
-
-def process(file):
- for line in file:
- print sanitise(line),
-
-def main():
- if len(sys.argv) > 1:
- for fn in sys.argv[1:]:
- with open(fn) as f:
- process(f)
- else:
- process(sys.stdin)
-
-if __name__ == '__main__':
- main()
-
diff --git a/tools/make-version-script.py b/tools/make-version-script.py
new file mode 100644
index 0000000..0d30aa3
--- /dev/null
+++ b/tools/make-version-script.py
@@ -0,0 +1,208 @@
+#!/usr/bin/python
+
+"""Construct a GNU ld or Debian dpkg version-script from a set of
+RFC822-style symbol lists.
+
+Usage:
+ make-version-script.py [--symbols SYMBOLS] [--unreleased-version VER]
+ [--dpkg "LIBRARY.so.0 LIBRARY0 #MINVER#"]
+ [--dpkg-build-depends-package LIBRARY-dev]
+ [FILES...]
+
+Each FILE starts with RFC822-style headers "Version:" (the name of the
+symbol version, e.g. FOO_1.2.3) and "Extends:" (either the previous
+version, or "-" if this is the first version). Next there is a blank
+line, then a list of C symbols one per line.
+
+Comments (lines starting with whitespace + "#") are allowed and ignored.
+
+If --symbols is given, SYMBOLS lists the symbols actually exported by
+the library (one per line). If --unreleased-version is given, any symbols
+in SYMBOLS but not in FILES are assigned to that version; otherwise, any
+such symbols cause an error.
+
+If --dpkg is given, produce a Debian dpkg-gensymbols file instead of a
+GNU ld version-script. The argument to --dpkg is the first line of the
+resulting symbols file, and --dpkg-build-depends-package can optionally
+be used to set the Build-Depends-Package field.
+
+This script originates in telepathy-glib <http://telepathy.freedesktop.org/> -
+please send us any changes that are needed.
+"""
+
+# Copyright (C) 2008-2010 Collabora Ltd. <http://www.collabora.co.uk/>
+# Copyright (C) 2008 Nokia Corporation
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved.
+
+import sys
+from getopt import gnu_getopt
+
+
+def e(format, *args):
+ sys.stderr.write((format + '\n') % args)
+
+
+def main(abifiles, symbols=None, unreleased_version=None,
+ dpkg=False, dpkg_first_line=None, dpkg_build_depends_package=None):
+
+ gnuld = not dpkg
+ symbol_set = None
+
+ if symbols is not None:
+ symbol_set = open(symbols, 'r').readlines()
+ symbol_set = map(str.strip, symbol_set)
+ symbol_set = set(symbol_set)
+
+ versioned_symbols = set()
+
+ dpkg_symbols = []
+ dpkg_versions = []
+
+ if dpkg:
+ assert dpkg_first_line is not None
+ print dpkg_first_line
+ if dpkg_build_depends_package is not None:
+ print "* Build-Depends-Package: %s" % dpkg_build_depends_package
+
+ for filename in abifiles:
+ lines = open(filename, 'r').readlines()
+
+ version = None
+ extends = None
+ release = None
+
+ for i, line in enumerate(lines):
+ line = line.strip()
+
+ if line.startswith('#'):
+ continue
+ elif not line:
+ # the transition betwen headers and symbols
+ cut = i + 1
+ break
+ elif line.lower().startswith('version:'):
+ line = line[8:].strip()
+ version = line
+ continue
+ elif line.lower().startswith('extends:'):
+ line = line[8:].strip()
+ extends = line
+ continue
+ elif line.lower().startswith('release:'):
+ release = line[8:].strip()
+ continue
+ else:
+ e('Could not understand line in %s header: %s', filename, line)
+ raise SystemExit(1)
+
+ else:
+ e('No symbols in %s', filename)
+ raise SystemExit(1)
+
+ if version is None:
+ e('No Versions: header in %s', filename)
+ raise SystemExit(1)
+
+ if extends is None:
+ e('No Extends: header in %s', filename)
+ raise SystemExit(1)
+
+ if release is None and dpkg:
+ e('No Release: header in %s', filename)
+ raise SystemExit(1)
+
+ if dpkg:
+ dpkg_versions.append('%s@%s %s' % (version, version, release))
+
+ lines = lines[cut:]
+
+ if gnuld:
+ print "%s {" % version
+ print " global:"
+
+ for symbol in lines:
+ symbol = symbol.strip()
+
+ if symbol.startswith('#'):
+ continue
+
+ if gnuld:
+ print " %s;" % symbol
+ elif dpkg:
+ dpkg_symbols.append('%s@%s %s' % (symbol, version, release))
+
+ if symbol in versioned_symbols:
+ raise AssertionError('Symbol %s is in version %s and an '
+ 'earlier version' % (symbol, version))
+
+ versioned_symbols.add(symbol)
+
+ if gnuld:
+ if extends == '-':
+ print " local:"
+ print " *;"
+ print "};"
+ else:
+ print "} %s;" % extends
+ print
+
+ if dpkg:
+ dpkg_symbols.sort()
+ dpkg_versions.sort()
+
+ for x in dpkg_versions:
+ print " %s" % x
+
+ for x in dpkg_symbols:
+ print " %s" % x
+
+ if symbol_set is not None:
+ missing = versioned_symbols - symbol_set
+
+ if missing:
+ e('These symbols have disappeared:')
+
+ for symbol in missing:
+ e(' %s', symbol)
+
+ raise SystemExit(1)
+
+ unreleased = symbol_set - versioned_symbols
+
+ if unreleased:
+ if unreleased_version is None:
+ e('Unversioned symbols are not allowed in releases:')
+
+ for symbol in unreleased:
+ e(' %s', symbol)
+
+ raise SystemExit(1)
+
+ if gnuld:
+ print "%s {" % unreleased_version
+ print " global:"
+
+ for symbol in unreleased:
+ print " %s;" % symbol
+
+ print "} %s;" % version
+
+
+if __name__ == '__main__':
+ options, argv = gnu_getopt (sys.argv[1:], '',
+ ['symbols=', 'unreleased-version=',
+ 'dpkg=', 'dpkg-build-depends-package='])
+
+ opts = {'dpkg': False}
+
+ for option, value in options:
+ if option == '--dpkg':
+ opts['dpkg'] = True
+ opts['dpkg_first_line'] = value
+ else:
+ opts[option.lstrip('-').replace('-', '_')] = value
+
+ main(argv, **opts)
diff --git a/tools/manager-file.py b/tools/manager-file.py
new file mode 100644
index 0000000..e1b51a6
--- /dev/null
+++ b/tools/manager-file.py
@@ -0,0 +1,187 @@
+#!/usr/bin/python
+
+# manager-file.py: generate .manager files and TpCMParamSpec arrays from the
+# same data (should be suitable for all connection managers that don't have
+# plugins)
+#
+# The master copy of this program is in the telepathy-glib repository -
+# please make any changes there.
+#
+# Copyright (c) Collabora Ltd. <http://www.collabora.co.uk/>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import re
+import sys
+
+_NOT_C_STR = re.compile(r'[^A-Za-z0-9_-]')
+
+def c_string(x):
+ # whitelist-based brute force and ignorance - escape nearly all punctuation
+ return '"' + _NOT_C_STR.sub(lambda c: r'\x%02x' % ord(c), x) + '"'
+
+def desktop_string(x):
+ return x.replace(' ', r'\s').replace('\n', r'\n').replace('\r', r'\r').replace('\t', r'\t')
+
+supported = list('sbuiqn')
+
+fdefaultencoders = {
+ 's': desktop_string,
+ 'b': (lambda b: b and '1' or '0'),
+ 'u': (lambda n: '%u' % n),
+ 'i': (lambda n: '%d' % n),
+ 'q': (lambda n: '%u' % n),
+ 'n': (lambda n: '%d' % n),
+ }
+for x in supported: assert x in fdefaultencoders
+
+gtypes = {
+ 's': 'G_TYPE_STRING',
+ 'b': 'G_TYPE_BOOLEAN',
+ 'u': 'G_TYPE_UINT',
+ 'i': 'G_TYPE_INT',
+ 'q': 'G_TYPE_UINT',
+ 'n': 'G_TYPE_INT',
+}
+for x in supported: assert x in gtypes
+
+gdefaultencoders = {
+ 's': c_string,
+ 'b': (lambda b: b and 'GINT_TO_POINTER (TRUE)' or 'GINT_TO_POINTER (FALSE)'),
+ 'u': (lambda n: 'GUINT_TO_POINTER (%u)' % n),
+ 'i': (lambda n: 'GINT_TO_POINTER (%d)' % n),
+ 'q': (lambda n: 'GUINT_TO_POINTER (%u)' % n),
+ 'n': (lambda n: 'GINT_TO_POINTER (%d)' % n),
+ }
+for x in supported: assert x in gdefaultencoders
+
+gdefaultdefaults = {
+ 's': 'NULL',
+ 'b': 'GINT_TO_POINTER (FALSE)',
+ 'u': 'GUINT_TO_POINTER (0)',
+ 'i': 'GINT_TO_POINTER (0)',
+ 'q': 'GUINT_TO_POINTER (0)',
+ 'n': 'GINT_TO_POINTER (0)',
+ }
+for x in supported: assert x in gdefaultdefaults
+
+gflags = {
+ 'has-default': 'TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT',
+ 'register': 'TP_CONN_MGR_PARAM_FLAG_REGISTER',
+ 'required': 'TP_CONN_MGR_PARAM_FLAG_REQUIRED',
+ 'secret': 'TP_CONN_MGR_PARAM_FLAG_SECRET',
+ 'dbus-property': 'TP_CONN_MGR_PARAM_FLAG_DBUS_PROPERTY',
+}
+
+def write_manager(f, manager, protos):
+ # pointless backwards compat section
+ print >> f, '[ConnectionManager]'
+ print >> f, 'BusName=org.freedesktop.Telepathy.ConnectionManager.' + manager
+ print >> f, 'ObjectPath=/org/freedesktop/Telepathy/ConnectionManager/' + manager
+
+ # protocols
+ for proto, params in protos.iteritems():
+ print >> f
+ print >> f, '[Protocol %s]' % proto
+
+ defaults = {}
+
+ for param, info in params.iteritems():
+ dtype = info['dtype']
+ flags = info.get('flags', '').split()
+ struct_field = info.get('struct_field', param.replace('-', '_'))
+ filter = info.get('filter', 'NULL')
+ filter_data = info.get('filter_data', 'NULL')
+ setter_data = 'NULL'
+
+ if 'default' in info:
+ default = fdefaultencoders[dtype](info['default'])
+ defaults[param] = default
+
+ if flags:
+ flags = ' ' + ' '.join(flags)
+ else:
+ flags = ''
+
+ print >> f, 'param-%s=%s%s' % (param, desktop_string(dtype), flags)
+
+ for param, default in defaults.iteritems():
+ print >> f, 'default-%s=%s' % (param, default)
+
+def write_c_params(f, manager, proto, struct, params):
+ print >> f, "static const TpCMParamSpec %s_%s_params[] = {" % (manager, proto)
+
+ for param, info in params.iteritems():
+ dtype = info['dtype']
+ flags = info.get('flags', '').split()
+ struct_field = info.get('struct_field', param.replace('-', '_'))
+ filter = info.get('filter', 'NULL')
+ filter_data = info.get('filter_data', 'NULL')
+ setter_data = 'NULL'
+
+ if 'default' in info:
+ default = gdefaultencoders[dtype](info['default'])
+ else:
+ default = gdefaultdefaults[dtype]
+
+ if flags:
+ flags = ' | '.join([gflags[flag] for flag in flags])
+ else:
+ flags = '0'
+
+ if struct is None or struct_field is None:
+ struct_offset = '0'
+ else:
+ struct_offset = 'G_STRUCT_OFFSET (%s, %s)' % (struct, struct_field)
+
+ print >> f, (''' { %s, %s, %s,
+ %s,
+ %s, /* default */
+ %s, /* struct offset */
+ %s, /* filter */
+ %s, /* filter data */
+ %s /* setter data */ },''' %
+ (c_string(param), c_string(dtype), gtypes[dtype], flags,
+ default, struct_offset, filter, filter_data, setter_data))
+
+ print >> f, " { NULL }"
+ print >> f, "};"
+
+if __name__ == '__main__':
+ environment = {}
+ execfile(sys.argv[1], environment)
+
+ filename = '%s/%s.manager' % (sys.argv[2], environment['MANAGER'])
+ try:
+ os.remove(filename)
+ except OSError:
+ pass
+ f = open(filename + '.tmp', 'w')
+ write_manager(f, environment['MANAGER'], environment['PARAMS'])
+ f.close()
+ os.rename(filename + '.tmp', filename)
+
+ filename = '%s/param-spec-struct.h' % sys.argv[2]
+ try:
+ os.remove(filename)
+ except OSError:
+ pass
+ f = open(filename + '.tmp', 'w')
+ for protocol in environment['PARAMS']:
+ write_c_params(f, environment['MANAGER'], protocol,
+ environment['STRUCTS'][protocol],
+ environment['PARAMS'][protocol])
+ f.close()
+ os.rename(filename + '.tmp', filename)
diff --git a/tools/shave.mk b/tools/shave.mk
new file mode 100644
index 0000000..53cb3bf
--- /dev/null
+++ b/tools/shave.mk
@@ -0,0 +1 @@
+QUIET_GEN = $(Q:@=@echo ' GEN '$@;)
diff --git a/tools/specparser.py b/tools/specparser.py
deleted file mode 100644
index 16b770e..0000000
--- a/tools/specparser.py
+++ /dev/null
@@ -1,885 +0,0 @@
-#
-# specparser.py
-#
-# Reads in a spec document and generates pretty data structures from it.
-#
-# Copyright (C) 2009 Collabora Ltd.
-#
-# This library is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or (at
-# your option) any later version.
-#
-# This library is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
-# for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this library; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# Authors: Davyd Madeley <davyd.madeley@collabora.co.uk>
-#
-
-import sys
-import xml.dom.minidom
-
-import xincludator
-
-XMLNS_TP = 'http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0'
-
-class UnknownAccess(Exception): pass
-class UnknownDirection(Exception): pass
-class UnknownType(Exception): pass
-class UnnamedItem(Exception): pass
-class UntypedItem(Exception): pass
-class UnsupportedArray(Exception): pass
-class BadNameForBindings(Exception): pass
-
-def getText(dom):
- try:
- if dom.childNodes[0].nodeType == dom.TEXT_NODE:
- return dom.childNodes[0].data
- else:
- return ''
- except IndexError:
- return ''
-
-def getChildrenByName(dom, namespace, name):
- return filter(lambda n: n.nodeType == n.ELEMENT_NODE and \
- n.namespaceURI == namespace and \
- n.localName == name,
- dom.childNodes)
-
-def build_name(namespace, name):
- """Returns a name by appending `name' to the namespace of this object.
- """
- return '.'.join(
- filter(lambda n: n is not None and n != '',
- [namespace, name.replace(' ', '')])
- )
-
-class Base(object):
- """The base class for any type of XML node in the spec that implements the
- 'name' attribute.
-
- Don't instantiate this class directly.
- """
- devhelp_name = ""
-
- def __init__(self, parent, namespace, dom):
- self.short_name = name = dom.getAttribute('name')
- self.namespace = namespace
- self.name = build_name(namespace, name)
- self.parent = parent
-
- try:
- self.docstring = getChildrenByName(dom, XMLNS_TP, 'docstring')[0]
- except IndexError:
- self.docstring = None
-
- try:
- self.added = getChildrenByName(dom, XMLNS_TP, 'added')[0]
- except IndexError:
- self.added = None
-
- try:
- self.deprecated = getChildrenByName(dom, XMLNS_TP, 'deprecated')[0]
- except IndexError:
- self.deprecated = None
-
- self.changed = getChildrenByName(dom, XMLNS_TP, 'changed')
-
- self.validate()
-
- def validate(self):
- if self.short_name == '':
- raise UnnamedItem("Node %s of %s has no name" % (
- self.__class__.__name__, self.parent))
-
- def get_type_name(self):
- return self.__class__.__name__
-
- def get_spec(self):
- return self.parent.get_spec()
-
- def get_root_namespace(self):
- return self.get_interface().name
-
- def get_interface(self):
- return self.parent.get_interface()
-
- def get_url(self):
- return "%s#%s" % (self.get_interface().get_url(), self.name)
-
- def _get_generic_with_ver(self, nnode, htmlclass, txt):
- if nnode is None:
- return ''
- else:
- # make a copy of this node, turn it into a HTML <div> tag
- node = nnode.cloneNode(True)
- node.tagName = 'div'
- node.baseURI = None
- node.setAttribute('class', htmlclass)
-
- try:
- node.removeAttribute('version')
-
- span = xml.dom.minidom.parseString(
- ('<span class="version">%s\n</span>' % txt) %
- nnode.getAttribute('version')).firstChild
- node.insertBefore(span, node.firstChild)
- except xml.dom.NotFoundErr:
- print >> sys.stderr, \
- 'WARNING: %s was %s, but gives no version' % (self, htmlclass)
-
- self._convert_to_html(node)
-
- return node.toxml().encode('ascii', 'xmlcharrefreplace')
-
- def get_added(self):
- return self._get_generic_with_ver(self.added, 'added',
- "Added in %s.")
-
- def get_deprecated(self):
- return self._get_generic_with_ver(self.deprecated, 'deprecated',
- "Deprecated since %s.")
-
- def get_changed(self):
- return '\n'.join(map(lambda n:
- self._get_generic_with_ver(n, 'changed', "Changed in %s."),
- self.changed))
-
- def get_docstring(self):
- """Get the docstring for this node, but do node substitution to
- rewrite types, interfaces, etc. as links.
- """
- if self.docstring is None:
- return ''
- else:
- # make a copy of this node, turn it into a HTML <div> tag
- node = self.docstring.cloneNode(True)
- node.tagName = 'div'
- node.baseURI = None
- node.setAttribute('class', 'docstring')
-
- self._convert_to_html(node)
-
- return node.toxml().encode('ascii', 'xmlcharrefreplace')
-
- def _convert_to_html(self, node):
- spec = self.get_spec()
- namespace = self.get_root_namespace()
-
- # rewrite <tp:rationale>
- for n in node.getElementsByTagNameNS(XMLNS_TP, 'rationale'):
- n.tagName = 'div'
- n.namespaceURI = None
- n.setAttribute('class', 'rationale')
-
- # rewrite <tp:type>
- for n in node.getElementsByTagNameNS(XMLNS_TP, 'type'):
- t = spec.lookup_type(getText(n))
- n.tagName = 'a'
- n.namespaceURI = None
- n.setAttribute('href', t.get_url())
-
- # rewrite <tp:member-ref>
- for n in node.getElementsByTagNameNS(XMLNS_TP, 'member-ref'):
- key = getText(n)
- try:
- o = spec.lookup(key, namespace=namespace)
- except KeyError:
- print >> sys.stderr, \
- "WARNING: Key '%s' not known in namespace '%s'" % (
- key, namespace)
- continue
-
- n.tagName = 'a'
- n.namespaceURI = None
- n.setAttribute('href', o.get_url())
- n.setAttribute('title', o.get_title())
-
- # rewrite <tp:dbus-ref>
- for n in node.getElementsByTagNameNS(XMLNS_TP, 'dbus-ref'):
- namespace = n.getAttribute('namespace')
- key = getText(n)
- try:
- o = spec.lookup(key, namespace=namespace)
- except KeyError:
- print >> sys.stderr, \
- "WARNING: Key '%s' not known in namespace '%s'" % (
- key, namespace)
- continue
-
- n.tagName = 'a'
- n.namespaceURI = None
- n.setAttribute('href', o.get_url())
- n.setAttribute('title', o.get_title())
-
- def get_title(self):
- return '%s %s' % (self.get_type_name(), self.name)
-
- def __repr__(self):
- return '%s(%s)' % (self.__class__.__name__, self.name)
-
-class DBusConstruct(Base):
- """Base class for signals, methods and properties."""
-
- def __init__(self, parent, namespace, dom):
- super(DBusConstruct, self).__init__(parent, namespace, dom)
-
- self.name_for_bindings = dom.getAttributeNS(XMLNS_TP,
- 'name-for-bindings')
-
- if not self.name_for_bindings:
- raise BadNameForBindings('%s has no name-for-bindings'
- % self)
-
- if self.name_for_bindings.replace('_', '') != self.short_name:
- raise BadNameForBindings('%s name-for-bindings = %s does not '
- 'match short_name = %s' % (self, self.name_for_bindings,
- self.short_name))
-
-class PossibleError(Base):
- def __init__(self, parent, namespace, dom):
- super(PossibleError, self).__init__(parent, namespace, dom)
-
- def get_error(self):
- spec = self.get_spec()
- try:
- return spec.errors[self.name]
- except KeyError:
- return External(self.name)
-
- def get_url(self):
- return self.get_error().get_url()
-
- def get_title(self):
- return self.get_error().get_title()
-
- def get_docstring(self):
- d = super(PossibleError, self).get_docstring()
- if d == '':
- return self.get_error().get_docstring()
- else:
- return d
-
-class Method(DBusConstruct):
- devhelp_name = "function"
-
- def __init__(self, parent, namespace, dom):
- super(Method, self).__init__(parent, namespace, dom)
-
- args = build_list(self, Arg, self.name,
- 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)
-
- for arg in args:
- if arg.direction == Arg.DIRECTION_IN or \
- arg.direction == Arg.DIRECTION_OUT:
- continue
-
- print >> sys.stderr, "WARNING: '%s' of method '%s' does not specify a suitable direction" % (arg, self)
-
- self.possible_errors = build_list(self, PossibleError, None,
- dom.getElementsByTagNameNS(XMLNS_TP, 'error'))
-
- def get_in_args(self):
- return ', '.join(map(lambda a: a.spec_name(), self.in_args))
-
- def get_out_args(self):
- if len(self.out_args) > 0:
- return ', '.join(map(lambda a: a.spec_name(), self.out_args))
- else:
- return 'nothing'
-
-class Typed(Base):
- """The base class for all typed nodes (i.e. Arg and Property).
-
- Don't instantiate this class directly.
- """
-
- def __init__(self, parent, namespace, dom):
- super(Typed, self).__init__(parent, namespace, dom)
-
- self.type = dom.getAttributeNS(XMLNS_TP, 'type')
- self.dbus_type = dom.getAttribute('type')
-
- # check we have a dbus type
- if self.dbus_type == '':
- raise UntypedItem("Node referred to by '%s' has no type" % dom.toxml())
- def get_type(self):
- return self.get_spec().lookup_type(self.type)
-
- def get_type_url(self):
- t = self.get_type()
- if t is None: return ''
- else: return t.get_url()
-
- def get_type_title(self):
- t = self.get_type()
- if t is None: return ''
- else: return t.get_title()
-
- def spec_name(self):
- return '%s: %s' % (self.dbus_type, self.short_name)
-
- def __repr__(self):
- return '%s(%s:%s)' % (self.__class__.__name__, self.name, self.dbus_type)
-
-class Property(DBusConstruct, Typed):
- ACCESS_READ = 1
- ACCESS_WRITE = 2
-
- ACCESS_READWRITE = ACCESS_READ | ACCESS_WRITE
-
- def __init__(self, parent, namespace, dom):
- super(Property, self).__init__(parent, namespace, dom)
-
- access = dom.getAttribute('access')
- if access == 'read':
- self.access = self.ACCESS_READ
- elif access == 'write':
- self.access = self.ACCESS_WRITE
- elif access == 'readwrite':
- self.access = self.ACCESS_READWRITE
- else:
- raise UnknownAccess("Unknown access '%s' on %s" % (access, self))
-
- def get_access(self):
- if self.access & self.ACCESS_READ and self.access & self.ACCESS_WRITE:
- return 'Read/Write'
- elif self.access & self.ACCESS_READ:
- return 'Read only'
- elif self.access & self.ACCESS_WRITE:
- return 'Write only'
-
-class AwkwardTelepathyProperty(Typed):
- def get_type_name(self):
- return 'Telepathy Property'
-
-class Arg(Typed):
- DIRECTION_IN, DIRECTION_OUT, DIRECTION_UNSPECIFIED = range(3)
-
- def __init__(self, parent, namespace, dom):
- super(Arg, self).__init__(parent, namespace, dom)
-
- direction = dom.getAttribute('direction')
- if direction == 'in':
- self.direction = self.DIRECTION_IN
- elif direction == 'out':
- self.direction = self.DIRECTION_OUT
- elif direction == '':
- self.direction = self.DIRECTION_UNSPECIFIED
- else:
- raise UnknownDirection("Unknown direction '%s' on %s" % (
- direction, self.parent))
-
-class Signal(DBusConstruct):
- def __init__(self, parent, namespace, dom):
- super(Signal, self).__init__(parent, namespace, dom)
-
- self.args = build_list(self, Arg, self.name,
- dom.getElementsByTagName('arg'))
-
- for arg in self.args:
- if arg.direction == Arg.DIRECTION_UNSPECIFIED:
- continue
-
- print >> sys.stderr, "WARNING: '%s' of signal '%s' does not specify a suitable direction" % (arg, self)
-
- def get_args(self):
- return ', '.join(map(lambda a: a.spec_name(), self.args))
-
-class External(object):
- """External objects are objects that are referred to in another spec.
-
- We have to attempt to look them up if at all possible.
- """
-
- def __init__(self, name):
- self.name = self.short_name = name
-
- def get_url(self):
- return None
-
- def get_title(self):
- return 'External %s' % self.name
-
- def get_docstring(self):
- return None
-
- def __repr__(self):
- return '%s(%s)' % (self.__class__.__name__, self.name)
-
-class Interface(Base):
- def __init__(self, parent, namespace, dom, spec_namespace):
- super(Interface, self).__init__(parent, namespace, dom)
-
- # If you're writing a spec with more than one top-level namespace, you
- # probably want to replace spec_namespace with a list.
- if self.name.startswith(spec_namespace + "."):
- self.short_name = self.name[len(spec_namespace) + 1:]
- else:
- self.short_name = self.name
-
- # build lists of methods, etc., in this interface
- self.methods = build_list(self, Method, self.name,
- dom.getElementsByTagName('method'))
- self.properties = build_list(self, Property, self.name,
- dom.getElementsByTagName('property'))
- self.signals = build_list(self, Signal, self.name,
- dom.getElementsByTagName('signal'))
- self.tpproperties = build_list(self, AwkwardTelepathyProperty,
- self.name, dom.getElementsByTagNameNS(XMLNS_TP, 'property'))
- self.handler_capability_tokens = build_list(self,
- HandlerCapabilityToken, self.name,
- dom.getElementsByTagNameNS(XMLNS_TP,
- 'handler-capability-token'))
- self.contact_attributes = build_list(self, ContactAttribute, self.name,
- dom.getElementsByTagNameNS(XMLNS_TP, 'contact-attribute'))
-
- # build a list of types in this interface
- self.types = parse_types(self, dom, self.name)
-
- # find out if this interface causes havoc
- self.causes_havoc = dom.getAttributeNS(XMLNS_TP, 'causes-havoc')
- if self.causes_havoc == '': self.causes_havoc = None
-
- # find out what we're required to also implement
- self.requires = map(lambda n: n.getAttribute('interface'),
- getChildrenByName(dom, XMLNS_TP, 'requires'))
-
- def get_interface(self):
- return self
-
- def get_requires(self):
- spec = self.get_spec()
-
- def lookup(r):
- try:
- return spec.lookup(r)
- except KeyError:
- return External(r)
-
- return map(lookup, self.requires)
-
- def get_url(self):
- return '%s.html' % self.name
-
-class Error(Base):
- def get_url(self):
- return 'errors.html#%s' % self.name
-
- def get_root_namespace(self):
- return self.namespace
-
-class DBusList(object):
- """Stores a list of a given DBusType. Provides some basic validation to
- determine whether or not the type is sane.
- """
- def __init__(self, child):
- self.child = child
-
- if isinstance(child, DBusType):
- self.ultimate = child
- self.depth = 1
-
- if self.child.array_name == '':
- raise UnsupportedArray("Type '%s' does not support being "
- "used in an array" % self.child.name)
- else:
- self.name = build_name(self.child.namespace,
- self.child.array_name)
- self.short_name = self.child.array_name
-
- elif isinstance(child, DBusList):
- self.ultimate = child.ultimate
- self.depth = child.depth + 1
- self.name = self.child.name + '_List'
- self.short_name = self.child.short_name + '_List'
-
- # check that our child can operate at this depth
- maxdepth = int(self.ultimate.array_depth)
- if self.depth > maxdepth:
- raise TypeError("Type '%s' has exceeded its maximum depth (%i)" % (self, maxdepth))
-
- else:
- raise TypeError("DBusList can contain only a DBusType or DBusList not '%s'" % child)
-
- self.dbus_type = 'a' + self.child.dbus_type
-
- def get_url(self):
- return self.ultimate.get_url()
-
- def get_title(self):
- return "Array of %s" % self.child.get_title()
-
- def __repr__(self):
- return 'Array(%s)' % self.child
-
-class DBusType(Base):
- """The base class for all D-Bus types referred to in the spec.
-
- Don't instantiate this class directly.
- """
-
- devhelp_name = "typedef"
-
- def __init__(self, parent, namespace, dom):
- super(DBusType, self).__init__(parent, namespace, dom)
-
- self.dbus_type = dom.getAttribute('type')
- self.array_name = dom.getAttribute('array-name')
- self.array_depth = dom.getAttribute('array-depth')
-
- def get_root_namespace(self):
- return self.namespace
-
- def get_breakdown(self):
- return ''
-
- def get_url(self):
- if isinstance(self.parent, Interface):
- html = self.parent.get_url()
- else:
- html = 'generic-types.html'
-
- return '%s#%s' % (html, self.name)
-
-class SimpleType(DBusType):
- def get_type_name(self):
- return 'Simple Type'
-
-class ExternalType(DBusType):
- def __init__(self, parent, namespace, dom):
- super(ExternalType, self).__init__(parent, namespace, dom)
-
- # FIXME: until we are able to cross reference external types to learn
- # about their array names, we're just going to assume they work like
- # this
- self.array_name = self.short_name + '_List'
-
- def get_type_name(self):
- return 'External Type'
-
-class StructLike(DBusType):
- """Base class for all D-Bus types that look kind of like Structs
-
- Don't instantiate this class directly.
- """
-
- class StructMember(Typed):
- def get_root_namespace(self):
- return self.parent.get_root_namespace()
-
- def __init__(self, parent, namespace, dom):
- super(StructLike, self).__init__(parent, namespace, dom)
-
- self.members = build_list(self, StructLike.StructMember, None,
- dom.getElementsByTagNameNS(XMLNS_TP, 'member'))
-
- def get_breakdown(self):
- str = ''
- str += '<ul>\n'
- for member in self.members:
- # attempt to lookup the member up in the type system
- t = member.get_type()
-
- str += '<li>%s &mdash; %s' % (member.name, member.dbus_type)
- if t: str += ' (<a href="%s" title="%s">%s</a>)' % (
- t.get_url(), t.get_title(), t.short_name)
- str += '</li>\n'
- str += member.get_docstring()
- str += '</ul>\n'
-
- return str
-
-class Mapping(StructLike):
- def __init__(self, parent, namespace, dom):
- super(Mapping, self).__init__(parent, namespace, dom)
-
- # rewrite the D-Bus type
- self.dbus_type = 'a{%s}' % ''.join(map(lambda m: m.dbus_type, self.members))
-
-class Struct(StructLike):
-
- devhelp_name = "struct"
-
- def __init__(self, parent, namespace, dom):
- super(Struct, self).__init__(parent, namespace, dom)
-
- # rewrite the D-Bus type
- self.dbus_type = '(%s)' % ''.join(map(lambda m: m.dbus_type, self.members))
-
-class EnumLike(DBusType):
- """Base class for all D-Bus types that look kind of like Enums
-
- Don't instantiate this class directly.
- """
- class EnumValue(Base):
- def __init__(self, parent, namespace, dom):
- super(EnumLike.EnumValue, self).__init__(parent, namespace, dom)
-
- # rewrite self.name
- self.short_name = dom.getAttribute('suffix')
- self.name = build_name(namespace, self.short_name)
-
- self.value = dom.getAttribute('value')
-
- super(EnumLike.EnumValue, self).validate()
-
- def validate(self):
- pass
-
- def get_root_namespace(self):
- return self.parent.get_root_namespace()
-
- def get_breakdown(self):
- str = ''
- str += '<ul>\n'
- for value in self.values:
- # attempt to lookup the member.name as a type in the type system
- str += '<li>%s (%s)</li>\n' % (value.short_name, value.value)
- str += value.get_added()
- str += value.get_changed()
- str += value.get_deprecated()
- str += value.get_docstring()
- str += '</ul>\n'
-
- return str
-
-class Enum(EnumLike):
-
- devhelp_name = "enum"
-
- def __init__(self, parent, namespace, dom):
- super(Enum, self).__init__(parent, namespace, dom)
-
- self.values = build_list(self, EnumLike.EnumValue, self.name,
- dom.getElementsByTagNameNS(XMLNS_TP, 'enumvalue'))
-
-class Flags(EnumLike):
- def __init__(self, parent, namespace, dom):
- super(Flags, self).__init__(parent, namespace, dom)
-
- self.values = build_list(self, EnumLike.EnumValue, self.name,
- dom.getElementsByTagNameNS(XMLNS_TP, 'flag'))
- self.flags = self.values # in case you're looking for it
-
-class TokenBase(Base):
-
- devhelp_name = "macro" # it's a constant, which is near enough...
- separator = '/'
-
- def __init__(self, parent, namespace, dom):
- super(TokenBase, self).__init__(parent, namespace, dom)
- self.name = namespace + '/' + self.short_name
-
-class ContactAttribute(TokenBase, Typed):
-
- def get_type_name(self):
- return 'Contact Attribute'
-
-class HandlerCapabilityToken(TokenBase):
-
- def get_type_name(self):
- return 'Handler Capability Token'
-
- def __init__(self, parent, namespace, dom):
- super(HandlerCapabilityToken, self).__init__(parent, namespace, dom)
-
- is_family = dom.getAttribute('is-family')
- assert is_family in ('yes', 'no', '')
- self.is_family = (is_family == 'yes')
-
-class SectionBase(object):
- """A SectionBase is an abstract base class for any type of node that can
- contain a <tp:section>, which means the top-level Spec object, or any
- Section object.
-
- It should not be instantiated directly.
- """
-
- def __init__(self, dom, spec_namespace):
-
- self.items = []
-
- def recurse(nodes):
- # iterate through the list of child nodes
- for node in nodes:
- if node.nodeType != node.ELEMENT_NODE: continue
-
- if node.tagName == 'node':
- # recurse into this level for interesting items
- recurse(node.childNodes)
- elif node.namespaceURI == XMLNS_TP and \
- node.localName == 'section':
- self.items.append(Section(self, None, node,
- spec_namespace))
- elif node.tagName == 'interface':
- self.items.append(Interface(self, None, node,
- spec_namespace))
-
- recurse(dom.childNodes)
-
-class Section(Base, SectionBase):
- def __init__(self, parent, namespace, dom, spec_namespace):
- Base.__init__(self, parent, namespace, dom)
- SectionBase.__init__(self, dom, spec_namespace)
-
- def get_root_namespace(self):
- return None
-
-class Spec(SectionBase):
- def __init__(self, dom, spec_namespace):
- # build a dictionary of errors in this spec
- try:
- errorsnode = dom.getElementsByTagNameNS(XMLNS_TP, 'errors')[0]
- self.errors = build_dict(self, Error,
- errorsnode.getAttribute('namespace'),
- errorsnode.getElementsByTagNameNS(XMLNS_TP, 'error'))
- except IndexError:
- self.errors = {}
-
- # build a list of generic types
- self.generic_types = reduce (lambda a, b: a + b,
- map(lambda l: parse_types(self, l),
- dom.getElementsByTagNameNS(XMLNS_TP, 'generic-types')),
- [])
-
- # create a top-level section for this Spec
- SectionBase.__init__(self, dom.documentElement, spec_namespace)
-
- # build a list of interfaces in this spec
- self.interfaces = []
- def recurse(items):
- for item in items:
- if isinstance(item, Section): recurse(item.items)
- elif isinstance(item, Interface): self.interfaces.append(item)
- recurse(self.items)
-
- # build a giant dictionary of everything (interfaces, methods, signals
- # and properties); also build a dictionary of types
- self.everything = {}
- self.types = {}
-
- for type in self.generic_types: self.types[type.short_name] = type
-
- for interface in self.interfaces:
- self.everything[interface.name] = interface
-
- for method in interface.methods:
- self.everything[method.name] = method
- for signal in interface.signals:
- self.everything[signal.name] = signal
- for property in interface.properties:
- self.everything[property.name] = property
- for property in interface.tpproperties:
- self.everything[property.name] = property
- for token in interface.contact_attributes:
- self.everything[token.name] = token
- for token in interface.handler_capability_tokens:
- self.everything[token.name] = token
-
- for type in interface.types:
- self.types[type.short_name] = type
-
- # get some extra bits for the HTML
- node = dom.getElementsByTagNameNS(XMLNS_TP, 'spec')[0]
- self.title = getText(getChildrenByName(node, XMLNS_TP, 'title')[0])
-
- try:
- self.version = getText(getChildrenByName(node, XMLNS_TP, 'version')[0])
- except IndexError:
- self.version = None
-
- self.copyrights = map(getText,
- getChildrenByName(node, XMLNS_TP, 'copyright'))
-
- try:
- license = getChildrenByName(node, XMLNS_TP, 'license')[0]
- license.tagName = 'div'
- license.namespaceURI = None
- license.setAttribute('class', 'license')
- self.license = license.toxml()
- except IndexError:
- self.license = ''
-
- # FIXME: we need to check all args for type correctness
-
- def get_spec(self):
- return self
-
- def lookup(self, name, namespace=None):
- key = build_name(namespace, name)
- return self.everything[key]
-
- def lookup_type(self, type_):
- if type_.endswith('[]'):
- return DBusList(self.lookup_type(type_[:-2]))
-
- if type_ == '': return None
- elif type_ in self.types:
- return self.types[type_]
-
- raise UnknownType("Type '%s' is unknown" % type_)
-
- def __repr__(self):
- return '%s(%s)' % (self.__class__.__name__, self.title)
-
-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.
-
- e.g. 'org.freedesktop.Telepathy.Channel' : Interface(Channel)
-
- Works for any Python object inheriting from 'Base' whose XML node
- implements the 'name' attribute.
- """
-
- def build_tuple(node):
- o = type_(parent, namespace, node)
- return(o.name, o)
-
- 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)
-
-def parse_types(parent, dom, namespace = 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'),
- (ExternalType, 'external-type'),
- ]
-
- types = []
-
- for (type_, tagname) in t:
- types += build_list(parent, type_, namespace,
- dom.getElementsByTagNameNS(XMLNS_TP, tagname))
-
- return types
-
-def parse(filename, spec_namespace):
- dom = xml.dom.minidom.parse(filename)
- xincludator.xincludate(dom, filename)
-
- spec = Spec(dom, spec_namespace)
-
- return spec
-
-if __name__ == '__main__':
- parse(sys.argv[1])
diff --git a/tools/telepathy-glib-env b/tools/telepathy-glib-env
new file mode 100755
index 0000000..8cc2995
--- /dev/null
+++ b/tools/telepathy-glib-env
@@ -0,0 +1,9 @@
+#!/bin/sh
+abs_top_builddir="/home/xclaesse/programmation/telepathy-logger"
+export abs_top_builddir
+LD_LIBRARY_PATH="${abs_top_builddir}/telepathy-glib/.libs${LD_LIBRARY_PATH:+":${LD_LIBRARY_PATH}"}"
+export LD_LIBRARY_PATH
+G_DEBUG="fatal_criticals,fatal_warnings${G_DEBUG:+",${G_DEBUG}"}"
+export G_DEBUG
+
+exec "$@"
diff --git a/tools/telepathy-glib-env.in b/tools/telepathy-glib-env.in
new file mode 100644
index 0000000..ddc47bf
--- /dev/null
+++ b/tools/telepathy-glib-env.in
@@ -0,0 +1,9 @@
+#!/bin/sh
+abs_top_builddir="@abs_top_builddir@"
+export abs_top_builddir
+LD_LIBRARY_PATH="${abs_top_builddir}/telepathy-glib/.libs${LD_LIBRARY_PATH:+":${LD_LIBRARY_PATH}"}"
+export LD_LIBRARY_PATH
+G_DEBUG="fatal_criticals,fatal_warnings${G_DEBUG:+",${G_DEBUG}"}"
+export G_DEBUG
+
+exec "$@"
diff --git a/tools/telepathy-glib.supp b/tools/telepathy-glib.supp
new file mode 100644
index 0000000..28bd5a0
--- /dev/null
+++ b/tools/telepathy-glib.supp
@@ -0,0 +1,390 @@
+# Valgrind error suppression file
+
+# ============================= libc ==================================
+
+{
+ ld.so initialization + selinux
+ Memcheck:Leak
+ ...
+ fun:_dl_init
+ obj:/lib/ld-*.so
+}
+
+{
+ dlopen initialization, triggered by handle-leak-debug code
+ Memcheck:Leak
+ ...
+ fun:__libc_dlopen_mode
+ fun:init
+ fun:backtrace
+ fun:handle_leak_debug_bt
+ fun:dynamic_ensure_handle
+ fun:tp_handle_ensure
+}
+
+# default.supp has these for 2.10, but they're too specific
+{
+ Debian libc6 (2.10.x, 2.11.x) stripped dynamic linker
+ Memcheck:Cond
+ fun:index
+ fun:expand_dynamic_string_token
+ fun:_dl_map_object
+ fun:map_doit
+ fun:_dl_catch_error
+ fun:do_preload
+ fun:dl_main
+ fun:_dl_sysdep_start
+ fun:_dl_start
+ obj:/lib/ld-*.so
+}
+{
+ Debian libc6 (2.9.x - 2.11.x) stripped dynamic linker
+ Memcheck:Cond
+ fun:_dl_relocate_object
+ fun:dl_main
+ fun:_dl_sysdep_start
+ fun:_dl_start
+ obj:/lib/ld-*.so
+}
+
+{
+ ld.so initialization on glibc 2.9
+ Memcheck:Cond
+ fun:strlen
+ fun:_dl_init_paths
+ fun:dl_main
+ fun:_dl_sysdep_start
+ fun:_dl_start
+ obj:/lib/ld-2.9.so
+}
+
+# ======================= libselinux on Debian amd64 =====================
+
+{
+ I have no idea what SELinux is doing but it's not my problem
+ Memcheck:Cond
+ ...
+ obj:/lib/libselinux.so.1
+ obj:/lib/libselinux.so.1
+ obj:/lib/libselinux.so.1
+}
+
+{
+ I have no idea what SELinux is doing but it's not my problem
+ Memcheck:Value8
+ ...
+ obj:/lib/libselinux.so.1
+ obj:/lib/libselinux.so.1
+ obj:/lib/libselinux.so.1
+}
+
+{
+ I have no idea what SELinux is doing but it's not my problem
+ Memcheck:Leak
+ ...
+ obj:/lib/libselinux.so.1
+ obj:/lib/libselinux.so.1
+ obj:/lib/libselinux.so.1
+}
+
+# ============================= GLib ==================================
+
+{
+ g_set_prgname copies its argument
+ Memcheck:Leak
+ ...
+ fun:g_set_prgname
+}
+
+{
+ one g_get_charset per child^Wprocess
+ Memcheck:Leak
+ ...
+ fun:g_get_charset
+}
+
+{
+ one g_get_home_dir per process
+ Memcheck:Leak
+ ...
+ fun:g_get_home_dir
+}
+
+{
+ GQuarks can't be freed
+ Memcheck:Leak
+ ...
+ fun:g_quark_from_static_string
+}
+
+{
+ GQuarks can't be freed
+ Memcheck:Leak
+ ...
+ fun:g_quark_from_string
+}
+
+{
+ interned strings can't be freed
+ Memcheck:Leak
+ ...
+ fun:g_intern_string
+}
+
+{
+ interned strings can't be freed
+ Memcheck:Leak
+ ...
+ fun:g_intern_static_string
+}
+
+{
+ shared global default g_main_context
+ Memcheck:Leak
+ ...
+ fun:g_main_context_new
+ fun:g_main_context_default
+}
+
+{
+ GTest initialization
+ Memcheck:Leak
+ ...
+ fun:g_test_init
+ fun:main
+}
+
+{
+ GTest admin
+ Memcheck:Leak
+ ...
+ fun:g_test_add_vtable
+}
+
+{
+ GTest pseudorandomness
+ Memcheck:Leak
+ ...
+ fun:g_rand_new_with_seed_array
+ fun:test_run_seed
+ ...
+ fun:g_test_run
+}
+
+{
+ GSLice initialization
+ Memcheck:Leak
+ ...
+ fun:g_malloc0
+ fun:g_slice_init_nomessage
+ fun:g_slice_alloc
+}
+
+# ============================= GObject ===============================
+
+{
+ g_type_init
+ Memcheck:Leak
+ ...
+ fun:g_type_init
+}
+
+{
+ g_type_init_with_debug_flags
+ Memcheck:Leak
+ ...
+ fun:g_type_init_with_debug_flags
+}
+
+{
+ g_type_register_static
+ Memcheck:Leak
+ ...
+ fun:g_type_register_static
+}
+
+{
+ g_type_add_interface_static
+ Memcheck:Leak
+ ...
+ fun:g_type_add_interface_static
+}
+
+{
+ initialization of interfaces
+ Memcheck:Leak
+ ...
+ fun:type_iface_vtable_base_init_Wm
+ fun:g_type_class_ref
+}
+
+# ============================= GIO ===================================
+
+{
+ GIO init
+ Memcheck:Leak
+ ...
+ fun:g_inet_address_class_intern_init
+}
+
+{
+ g_simple_async_result class
+ Memcheck:Leak
+ ...
+ fun:g_type_class_ref
+ ...
+ fun:g_simple_async_result_new
+}
+
+# ============================= dbus-glib =============================
+
+{
+ registering marshallers is permanent
+ Memcheck:Leak
+ ...
+ fun:dbus_g_object_register_marshaller_array
+ fun:dbus_g_object_register_marshaller
+}
+
+{
+ dbus-glib specialized GTypes are permanent
+ Memcheck:Leak
+ ...
+ fun:dbus_g_type_specialized_init
+}
+
+{
+ libdbus shared connection
+ Memcheck:Leak
+ ...
+ fun:dbus_g_bus_get
+}
+
+{
+ dbus-gobject registrations aren't freed unless we fall off the bus
+ Memcheck:Leak
+ ...
+ fun:g_slist_append
+ fun:dbus_g_connection_register_g_object
+}
+
+{
+ DBusGProxy slots aren't freed unless we fall off the bus
+ Memcheck:Leak
+ ...
+ fun:dbus_connection_allocate_data_slot
+ ...
+ fun:dbus_g_proxy_constructor
+}
+
+{
+ error registrations are for life, not just for Christmas
+ Memcheck:Leak
+ ...
+ fun:dbus_g_error_domain_register
+}
+
+{
+ DBusGProxy class init
+ Memcheck:Leak
+ ...
+ fun:dbus_g_proxy_class_init
+}
+
+# ============================= telepathy-glib ========================
+
+{
+ tp_dbus_daemon_constructor @daemons once per DBusConnection
+ Memcheck:Leak
+ ...
+ fun:g_slice_alloc
+ fun:tp_dbus_daemon_constructor
+}
+
+{
+ tp_proxy_subclass_add_error_mapping refs the enum
+ Memcheck:Leak
+ ...
+ fun:g_type_class_ref
+ fun:tp_proxy_subclass_add_error_mapping
+}
+
+{
+ tp_proxy_or_subclass_hook_on_interface_add never frees its list
+ Memcheck:Leak
+ ...
+ fun:tp_proxy_or_subclass_hook_on_interface_add
+}
+
+{
+ tp_dbus_daemon_constructor filter not freed til we fall off the bus
+ Memcheck:Leak
+ ...
+ fun:dbus_connection_add_filter
+ fun:tp_dbus_daemon_constructor
+}
+
+{
+ tp_g_socket_address_from_variant reffing GNIO types
+ Memcheck:Leak
+ ...
+ fun:g_type_class_ref
+ ...
+ fun:tp_g_socket_address_from_variant
+}
+
+{
+ creating classes for DBusGProxy
+ Memcheck:Leak
+ ...
+ fun:g_type_class_ref
+ ...
+ fun:g_object_new
+ ...
+ fun:tp_proxy_borrow_interface_by_id
+}
+
+{
+ creating classes for tp_dbus_daemon_new
+ Memcheck:Leak
+ ...
+ fun:g_type_class_ref
+ ...
+ fun:g_object_new
+ ...
+ fun:tp_dbus_daemon_new
+}
+
+{
+ creating classes for TpCHannel
+ Memcheck:Leak
+ ...
+ fun:g_type_class_ref
+ ...
+ fun:g_object_new
+ ...
+ fun:tp_channel_new
+}
+
+{
+ creating a boxed type to use in TpCapabilities
+ Memcheck:Leak
+ ...
+ fun:g_type_class_ref
+ ...
+ fun:g_param_spec_boxed
+ fun:tp_capabilities_class_intern_init
+}
+
+# ============================= questionable ==========================
+
+{
+ creating classes for instances (this is a pretty big hammer)
+ Memcheck:Leak
+ ...
+ fun:g_type_class_ref
+ ...
+ fun:g_type_create_instance
+ ...
+ fun:g_param_spec_string
+}
diff --git a/tools/telepathy.am b/tools/telepathy.am
index 5e78dfd..f696ef3 100644
--- a/tools/telepathy.am
+++ b/tools/telepathy.am
@@ -42,14 +42,14 @@ else
@exit 2;
endif
-%.tar.bz2.asc: %.tar.bz2
+%.tar.gz.asc: %.tar.gz
$(AM_V_GEN)gpg --detach-sign --armor $@
-@PACKAGE@-@VERSION@.tar.bz2: _is-release-check check distcheck
+@PACKAGE@-@VERSION@.tar.gz: _is-release-check check distcheck
maintainer-prepare-release: _is-release-check all distcheck release-mail
git tag -s @PACKAGE@-@VERSION@ -m @PACKAGE@' '@VERSION@
- gpg --detach-sign --armor @PACKAGE@-@VERSION@.tar.bz2
+ gpg --detach-sign --armor @PACKAGE@-@VERSION@.tar.gz
release-mail: NEWS
$(AM_V_GEN)(python $(top_srcdir)/tools/make-release-mail.py \
@@ -59,13 +59,13 @@ release-mail: NEWS
maintainer-upload-release: _maintainer-upload-release
_maintainer-upload-release-check: _is-release-check
- test -f @PACKAGE@-@VERSION@.tar.bz2
- test -f @PACKAGE@-@VERSION@.tar.bz2.asc
- gpg --verify @PACKAGE@-@VERSION@.tar.bz2.asc
+ test -f @PACKAGE@-@VERSION@.tar.gz
+ test -f @PACKAGE@-@VERSION@.tar.gz.asc
+ gpg --verify @PACKAGE@-@VERSION@.tar.gz.asc
_maintainer-upload-release: _maintainer-upload-release-check
- rsync -vzP @PACKAGE@-@VERSION@.tar.bz2 telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/releases/@PACKAGE@/@PACKAGE@-@VERSION@.tar.bz2
- rsync -vzP @PACKAGE@-@VERSION@.tar.bz2.asc telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/releases/@PACKAGE@/@PACKAGE@-@VERSION@.tar.bz2.asc
+ rsync -vzP @PACKAGE@-@VERSION@.tar.gz telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/releases/@PACKAGE@/@PACKAGE@-@VERSION@.tar.gz
+ rsync -vzP @PACKAGE@-@VERSION@.tar.gz.asc telepathy.freedesktop.org:/srv/telepathy.freedesktop.org/www/releases/@PACKAGE@/@PACKAGE@-@VERSION@.tar.gz.asc
maintainer-make-release: maintainer-prepare-release maintainer-upload-release
@echo "Now:"
diff --git a/tools/valgrind.mk b/tools/valgrind.mk
index ab146d4..25a3488 100644
--- a/tools/valgrind.mk
+++ b/tools/valgrind.mk
@@ -2,7 +2,7 @@ VALGRIND = valgrind --tool=memcheck \
--verbose \
--leak-check=full \
--leak-resolution=high \
- --suppressions=$(top_srcdir)/tests/suppressions/tpl.supp \
+ --suppressions=$(top_srcdir)/tools/telepathy-glib.supp \
--child-silent-after-fork=yes \
--num-callers=20 \
--gen-suppressions=all
diff --git a/tools/with-session-bus.sh b/tools/with-session-bus.sh
index 063bd7e..b3038cd 100644..100755
--- a/tools/with-session-bus.sh
+++ b/tools/with-session-bus.sh
@@ -59,7 +59,9 @@ cleanup ()
{
pid=`head -n1 $me-$$.pid`
if test -n "$pid" ; then
- echo "Killing temporary bus daemon: $pid" >&2
+ if [ -n "$VERBOSE_TESTS" ]; then
+ echo "Killing temporary bus daemon: $pid" >&2
+ fi
kill -INT "$pid"
fi
rm -f $me-$$.address
@@ -69,12 +71,16 @@ cleanup ()
trap cleanup INT HUP TERM
dbus-daemon $dbus_daemon_args
-{ echo -n "Temporary bus daemon is "; cat $me-$$.address; } >&2
-{ echo -n "Temporary bus daemon PID is "; head -n1 $me-$$.pid; } >&2
+if [ -n "$VERBOSE_TESTS" ]; then
+ { echo -n "Temporary bus daemon is "; cat $me-$$.address; } >&2
+ { echo -n "Temporary bus daemon PID is "; head -n1 $me-$$.pid; } >&2
+fi
e=0
DBUS_SESSION_BUS_ADDRESS="`cat $me-$$.address`"
export DBUS_SESSION_BUS_ADDRESS
+DBUS_SESSION_BUS_PID="`cat $me-$$.pid`"
+export DBUS_SESSION_BUS_PID
if [ -n "$WITH_SESSION_BUS_FORK_DBUS_MONITOR" ] ; then
echo -n "Forking dbus-monitor $WITH_SESSION_BUS_FORK_DBUS_MONITOR_OPT" >&2
diff --git a/tools/xincludator.py b/tools/xincludator.py
index 63e106a..63e106a 100755..100644
--- a/tools/xincludator.py
+++ b/tools/xincludator.py