diff options
author | Xavier Claessens <xavier.claessens@collabora.co.uk> | 2012-07-02 15:37:05 +0200 |
---|---|---|
committer | Xavier Claessens <xavier.claessens@collabora.co.uk> | 2012-07-03 12:09:56 +0200 |
commit | 4b7a97be0f8250af48c5b9f97cace813bc64c0f8 (patch) | |
tree | d438c36ea84e7b08d2d1c4abf0b197f1b4c81275 /tools | |
parent | b1046b3ee4cdd00323a4267a994dc67865a170b0 (diff) |
Update tools/ copy from telepathy-glib
This avoid single include from generated code
Diffstat (limited to 'tools')
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 "##" 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_##x (\\' % (self.prefix_, self.node_name_lc)) - self.h(' * klass, my_object_###x)') + self.d(' * klass, my_object_##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 — %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 |