Exemple #1
0
    def process(self, ref):
        assert ref.namespaceURI == NS_TP

        def get_closest_parent(el, needle):
            node = el
            while node is not None and node.localName != needle:
                node = node.parentNode
            return node

        local = get_descendant_text(ref).strip()
        if ref.localName == 'member-ref':
            ns = get_closest_parent(ref, 'interface').getAttribute('name')
            path = ns + '.' + local.strip()
        else:
            if ref.hasAttribute('namespace'):
                ns = ref.getAttribute('namespace').replace(
                    'ofdT', 'org.freedesktop.Telepathy')
                path = ns + '.' + local.strip()
            else:
                path = local

        target = self.targets.get(path)

        if target is None:
            parent = get_closest_parent(
                ref, 'interface') or get_closest_parent(ref, 'error')
            parent_name = parent.getAttribute('name')
            if (path + parent_name).find('.DRAFT') == -1 and (
                    path + parent_name).find('.FUTURE') == -1:
                print(('WARNING: Failed to resolve %s to "%s" in "%s"' %
                       (ref.localName, path, parent_name)),
                      file=stderr)
            return path

        if ref.localName == 'member-ref':
            if target.kind == target.KIND_PROPERTY:
                return '\\link %s %s \\endlink' % (target.member_link,
                                                   target.member_text)
            else:
                return target.member_text
        else:
            if target.kind == target.KIND_PROPERTY:
                return '\\link %s %s \\endlink' % (target.dbus_link,
                                                   target.dbus_text)
            else:
                return target.dbus_text
    def process(self, ref):
        assert ref.namespaceURI == NS_TP

        def get_closest_parent(el, needle):
            node = el
            while node is not None and node.localName != needle:
                node = node.parentNode
            return node

        local = get_descendant_text(ref).strip()
        if ref.localName == 'member-ref':
            ns = get_closest_parent(ref, 'interface').getAttribute('name')
            path = ns + '.' + local.strip()
        else:
            if ref.hasAttribute('namespace'):
                ns = ref.getAttribute('namespace').replace('ofdT', 'org.freedesktop.Telepathy')
                path = ns + '.' + local.strip()
            else:
                path = local

        target = self.targets.get(path)

        if target is None:
            parent = get_closest_parent(ref, 'interface') or get_closest_parent(ref, 'error')
            parent_name = parent.getAttribute('name')
            if (path + parent_name).find('.DRAFT') == -1 and (path + parent_name).find('.FUTURE') == -1:
                print >> stderr, 'WARNING: Failed to resolve %s to "%s" in "%s"' % (
                        ref.localName, path, parent_name)
            return path

        if ref.localName == 'member-ref':
            if target.kind == target.KIND_PROPERTY:
                return '\\link %s %s \\endlink' % (target.member_link, target.member_text)
            else:
                return target.member_text
        else:
            if target.kind == target.KIND_PROPERTY:
                return '\\link %s %s \\endlink' % (target.dbus_link, target.dbus_text)
            else:
                return target.dbus_text
def format_docstring(el, indent=' * ', brackets=None, maxwidth=80):
    docstring_el = None

    for x in el.childNodes:
        if x.namespaceURI == NS_TP and x.localName == 'docstring':
            docstring_el = x

    if not docstring_el:
        return ''

    lines = []

    if docstring_el.getAttribute('xmlns') == 'http://www.w3.org/1999/xhtml':
        splitted = ''.join([el.toxml() for el in docstring_el.childNodes
                            ]).strip(' ').strip('\n').split('\n')
        level = min([
            not match and maxsize or match.end() - 1
            for match in [re.match('^ *[^ ]', line) for line in splitted]
        ])
        assert level != maxsize
        lines = [line[level:].replace('\\', '\\\\') for line in splitted]
    else:
        content = xml_escape(
            get_descendant_text(docstring_el).replace('\n', ' ').strip())

        while content.find('  ') != -1:
            content = content.replace('  ', ' ')

        left = maxwidth - len(indent) - 1
        line = ''

        while content:
            step = (content.find(' ') + 1) or len(content)

            if step > left:
                lines.append(line)
                line = ''
                left = maxwidth - len(indent) - 1

            left = left - step
            line = line + content[:step]
            content = content[step:]

        if line:
            lines.append(line.replace('\\', '\\\\'))

    output = []

    if lines:
        if brackets:
            output.append(brackets[0])
        else:
            output.append(indent)

        output.append('\n')

    for line in lines:
        output.append(indent)
        output.append(line)
        output.append('\n')

    if lines and brackets:
        output.append(brackets[1])
        output.append('\n')

    return ''.join(output)
    def __call__(self):
        # Emit comment header

        self.both('/* Generated from ')
        self.both(get_descendant_text(get_by_path(self.spec, 'title')))
        version = get_by_path(self.spec, "version")

        if version:
            self.both(', version ' + get_descendant_text(version))

        self.both(' */\n')

        # Gather info on available and required types

        self.gather_required()

        if self.must_define:
            self.decl('\n')
            self.decl('#ifndef %s\n' % self.must_define)
            self.decl('#error %s\n' % self.must_define)
            self.decl('#endif')

        self.decl('\n')

        if self.extraincludes:
            for include in self.extraincludes.split(','):
                self.decl('#include %s\n' % include)

        self.decl("""
#include <QtGlobal>

#include <QByteArray>
#include <QString>
#include <QStringList>
#include <QVariantList>
#include <QVariantMap>

#include <QDBusArgument>
#include <QDBusMetaType>
#include <QDBusObjectPath>
#include <QDBusSignature>
#include <QDBusVariant>

#include <TelepathyQt/Global>

/**
 * \\addtogroup typesconstants Types and constants
 *
 * Enumerated, flag, structure, list and mapping types and utility constants.
 */

/**
 * \\defgroup struct Structure types
 * \\ingroup typesconstants
 *
 * Structure types generated from the specification.
 */

/**
 * \\defgroup list List types
 * \\ingroup typesconstants
 *
 * List types generated from the specification.
 */

/**
 * \\defgroup mapping Mapping types
 * \\ingroup typesconstants
 *
 * Mapping types generated from the specification.
 */

""")

        if self.must_define:
            self.impl("""
#define %s""" % self.must_define)

        self.impl("""
#include "%s"
""" % self.realinclude)

        self.both("""
namespace %s
{
""" % self.namespace)

        # Emit type definitions for types provided in the spec

        self.provide_all()

        # Emit type registration function

        self.decl("""
} // namespace %s

""" % self.namespace)

        self.impl("""\
TP_QT_NO_EXPORT void _registerTypes()
{
    static bool registered = false;
    if (registered)
        return;
    registered = true;

""")

        # Emit Qt metatype declarations

        self.to_declare.sort()

        for metatype in self.to_declare:
            self.decl('Q_DECLARE_METATYPE(%s)\n' % metatype)
            self.impl('    qDBusRegisterMetaType<%s>();\n' % ((metatype.endswith('>') and metatype + ' ') or metatype))

        self.impl("""\
}

} // namespace %s
""" % self.namespace)

        # Write output to files

        open(self.declfile, 'w').write(''.join(self.decls).encode("utf-8"))
        open(self.implfile, 'w').write(''.join(self.impls).encode("utf-8"))
Exemple #5
0
    def __call__(self):
        # Emit comment header

        self.both('/* Generated from ')
        self.both(get_descendant_text(get_by_path(self.spec, 'title')))
        version = get_by_path(self.spec, "version")

        if version:
            self.both(', version ' + get_descendant_text(version))

        self.both(' */\n')

        # Gather info on available and required types

        self.gather_required()

        if self.must_define:
            self.decl('\n')
            self.decl('#ifndef %s\n' % self.must_define)
            self.decl('#error %s\n' % self.must_define)
            self.decl('#endif')

        self.decl('\n')

        if self.extraincludes:
            for include in self.extraincludes.split(','):
                self.decl('#include %s\n' % include)

        self.decl("""
#include <QtGlobal>

#include <QByteArray>
#include <QString>
#include <QStringList>
#include <QVariantList>
#include <QVariantMap>

#include <QDBusArgument>
#include <QDBusMetaType>
#include <QDBusObjectPath>
#include <QDBusSignature>
#include <QDBusVariant>

#include <TelepathyQt/Global>

/**
 * \\addtogroup typesconstants Types and constants
 *
 * Enumerated, flag, structure, list and mapping types and utility constants.
 */

/**
 * \\defgroup struct Structure types
 * \\ingroup typesconstants
 *
 * Structure types generated from the specification.
 */

/**
 * \\defgroup list List types
 * \\ingroup typesconstants
 *
 * List types generated from the specification.
 */

/**
 * \\defgroup mapping Mapping types
 * \\ingroup typesconstants
 *
 * Mapping types generated from the specification.
 */

""")

        if self.must_define:
            self.impl("""
#define %s""" % self.must_define)

        self.impl("""
#include "%s"
""" % self.realinclude)

        self.both("""
namespace %s
{
""" % self.namespace)

        # Emit type definitions for types provided in the spec

        self.provide_all()

        # Emit type registration function

        self.decl("""
} // namespace %s

""" % self.namespace)

        self.impl("""\
TP_QT_NO_EXPORT void _registerTypes()
{
    static bool registered = false;
    if (registered)
        return;
    registered = true;

""")

        # Emit Qt metatype declarations

        self.to_declare.sort()

        for metatype in self.to_declare:
            self.decl('Q_DECLARE_METATYPE(%s)\n' % metatype)
            self.impl(
                '    qDBusRegisterMetaType<%s>();\n' %
                ((metatype.endswith('>') and metatype + ' ') or metatype))

        self.impl("""\
}

} // namespace %s
""" % self.namespace)

        # Write output to files

        open(self.declfile, 'w').write(''.join(self.decls).encode("utf-8"))
        open(self.implfile, 'w').write(''.join(self.impls).encode("utf-8"))
Exemple #6
0
    def __call__(self):
        # Header
        self.h('/* Generated from ')
        self.h(get_descendant_text(get_by_path(self.spec, 'title')))
        version = get_by_path(self.spec, "version")

        if version:
            self.h(', version ' + get_descendant_text(version))

        self.h("""
 */
 """)

        if self.must_define:
            self.h("""
#ifndef %s
#error %s
#endif
""" % (self.must_define, self.must_define))

        self.h("""
#include <QFlags>

/**
 * \\addtogroup typesconstants Types and constants
 *
 * Enumerated, flag, structure, list and mapping types and utility constants.
 */

/**
 * \\defgroup flagtypeconsts Flag type constants
 * \\ingroup typesconstants
 *
 * Types generated from the specification representing bit flag constants and
 * combinations of them (bitfields).
 */

/**
 * \\defgroup enumtypeconsts Enumerated type constants
 * \\ingroup typesconstants
 *
 * Types generated from the specification representing enumerated types ie.
 * types the values of which are mutually exclusive integral constants.
 */

/**
 * \\defgroup ifacestrconsts Interface string constants
 * \\ingroup typesconstants
 *
 * D-Bus interface names of the interfaces in the specification.
 */

/**
 * \\defgroup errorstrconsts Error string constants
 * \\ingroup typesconstants
 *
 * Names of the D-Bus errors in the specification.
 */
""")

        # Begin namespace
        self.h("""
namespace %s
{
""" % self.namespace)

        # Flags
        for flags in self.spec.getElementsByTagNameNS(NS_TP, 'flags'):
            self.do_flags(flags)

        # Enums
        for enum in self.spec.getElementsByTagNameNS(NS_TP, 'enum'):
            self.do_enum(enum)

        # End namespace
        self.h("""\
}

""")

        # Interface names
        for iface in self.spec.getElementsByTagName('interface'):
            self.h("""\
/**
 * \\ingroup ifacestrconsts
 *
 * The interface name "%(name)s".
 */
#define %(DEFINE)s "%(name)s"

""" % {'name' : iface.getAttribute('name'),
       'DEFINE' : self.prefix + 'INTERFACE_' + get_by_path(iface, '../@name').upper().replace('/', '')})

        # Error names
        for error in get_by_path(self.spec, 'errors/error'):
            name = error.getAttribute('name')
            fullname = get_by_path(error, '../@namespace') + '.' + name.replace(' ', '')
            define = self.prefix + 'ERROR_' + name.replace(' ', '_').replace('.', '_').upper()
            self.h("""\
/**
 * \\ingroup errorstrconsts
 *
 * The error name "%(fullname)s".
%(docstring)s\
 */
#define %(DEFINE)s "%(fullname)s"

""" % {'fullname' : fullname,
       'docstring': format_docstring(error),
       'DEFINE' : define})
def format_docstring(el, refs, indent=' * ', brackets=None, maxwidth=80):
    docstring_el = None

    for x in el.childNodes:
        if x.namespaceURI == NS_TP and x.localName == 'docstring':
            docstring_el = x

    if not docstring_el:
        return ''

    lines = []

    # escape backslashes, so they won't be interpreted starting doxygen commands and we can later
    # insert doxygen commands we actually want
    def escape_slashes(x):
        if x.nodeType == x.TEXT_NODE:
            x.data = x.data.replace('\\', '\\\\')
        elif x.nodeType == x.ELEMENT_NODE:
            for y in x.childNodes:
                escape_slashes(y)
        else:
            return

    escape_slashes(docstring_el)
    doc = docstring_el.ownerDocument

    for n in docstring_el.getElementsByTagNameNS(NS_TP, 'rationale'):
        nested = n.getElementsByTagNameNS(NS_TP, 'rationale')
        if nested:
            raise Xzibit(n, nested[0])

        div = doc.createElement('div')
        div.setAttribute('class', 'rationale')

        for rationale_body in n.childNodes:
            div.appendChild(rationale_body.cloneNode(True))

        n.parentNode.replaceChild(div, n)

    if docstring_el.getAttribute('xmlns') == 'http://www.w3.org/1999/xhtml':
        for ref in docstring_el.getElementsByTagNameNS(NS_TP, 'member-ref') + docstring_el.getElementsByTagNameNS(NS_TP, 'dbus-ref'):
            nested = ref.getElementsByTagNameNS(NS_TP, 'member-ref') + ref.getElementsByTagNameNS(NS_TP, 'dbus-ref')
            if nested:
                raise Xzibit(n, nested[0])

            text = doc.createTextNode(' \\endhtmlonly ')
            text.data += refs.process(ref)
            text.data += ' \\htmlonly '

            ref.parentNode.replaceChild(text, ref)

        splitted = ''.join([el.toxml() for el in docstring_el.childNodes]).strip(' ').strip('\n').split('\n')
        level = min([not match and maxint or match.end() - 1 for match in [re.match('^ *[^ ]', line) for line in splitted]])
        assert level != maxint
        lines = ['\\htmlonly'] + [line[level:] for line in splitted] + ['\\endhtmlonly']
    else:
        content = xml_escape(get_descendant_text(docstring_el).replace('\n', ' ').strip())

        while content.find('  ') != -1:
            content = content.replace('  ', ' ')

        left = maxwidth - len(indent) - 1
        line = ''

        while content:
            step = (content.find(' ') + 1) or len(content)

            if step > left:
                lines.append(line)
                line = ''
                left = maxwidth - len(indent) - 1

            left = left - step
            line = line + content[:step]
            content = content[step:]

        if line:
            lines.append(line)

    output = []

    if lines:
        if brackets:
            output.append(brackets[0])
        else:
            output.append(indent)

        output.append('\n')

    for line in lines:
        output.append(indent)
        output.append(line)
        output.append('\n')

    if lines and brackets:
        output.append(brackets[1])
        output.append('\n')

    return ''.join(output)
    def __call__(self):
        # Header
        self.h('/* Generated from ')
        self.h(get_descendant_text(get_by_path(self.spec, 'title')))
        version = get_by_path(self.spec, "version")

        if version:
            self.h(', version ' + get_descendant_text(version))

        self.h("""
 */
 """)

        if self.must_define:
            self.h("""
#ifndef %s
#error %s
#endif
""" % (self.must_define, self.must_define))

        self.h("""
#include <QFlags>

/**
 * \\addtogroup typesconstants Types and constants
 *
 * Enumerated, flag, structure, list and mapping types and utility constants.
 */

/**
 * \\defgroup flagtypeconsts Flag type constants
 * \\ingroup typesconstants
 *
 * Types generated from the specification representing bit flag constants and
 * combinations of them (bitfields).
 */

/**
 * \\defgroup enumtypeconsts Enumerated type constants
 * \\ingroup typesconstants
 *
 * Types generated from the specification representing enumerated types ie.
 * types the values of which are mutually exclusive integral constants.
 */

/**
 * \\defgroup ifacestrconsts Interface string constants
 * \\ingroup typesconstants
 *
 * D-Bus interface names of the interfaces in the specification.
 */

/**
 * \\defgroup errorstrconsts Error string constants
 * \\ingroup typesconstants
 *
 * Names of the D-Bus errors in the specification.
 */
""")

        # Begin namespace
        self.h("""
namespace %s
{
""" % self.namespace)

        # Flags
        for flags in self.spec.getElementsByTagNameNS(NS_TP, 'flags'):
            self.do_flags(flags)

        # Enums
        for enum in self.spec.getElementsByTagNameNS(NS_TP, 'enum'):
            self.do_enum(enum)

        # End namespace
        self.h("""\
}

""")

        # Interface names
        for iface in self.spec.getElementsByTagName('interface'):
            if self.old_prefix:
                self.h(
                    """\
/**
 * \\ingroup ifacestrconsts
 *
 * The interface name "%(name)s".
 */
#define %(DEFINE)s "%(name)s"

""" % {
                        'name':
                        iface.getAttribute('name'),
                        'DEFINE':
                        self.old_prefix + 'INTERFACE_' + get_by_path(
                            iface, '../@name').upper().replace('/', '')
                    })

            if self.define_prefix:
                self.h(
                    """\
/**
 * \\ingroup ifacestrconsts
 *
 * The interface name "%(name)s" as a QLatin1String, usable in QString requiring contexts even when
 * building with Q_NO_CAST_FROM_ASCII defined.
 */
#define %(DEFINE)s QLatin1String("%(name)s")

""" % {
                        'name':
                        iface.getAttribute('name'),
                        'DEFINE':
                        self.define_prefix + 'IFACE_' + get_by_path(
                            iface, '../@name').upper().replace('/', '')
                    })

        # Error names
        for error in get_by_path(self.spec, 'errors/error'):
            name = error.getAttribute('name')
            fullname = get_by_path(
                error, '../@namespace') + '.' + name.replace(' ', '')

            if self.old_prefix:
                define = self.old_prefix + 'ERROR_' + name.replace(
                    ' ', '_').replace('.', '_').upper()
                self.h(
                    """\
/**
 * \\ingroup errorstrconsts
 *
 * The error name "%(fullname)s".
%(docstring)s\
 */
#define %(DEFINE)s "%(fullname)s"

""" % {
                        'fullname': fullname,
                        'docstring': format_docstring(error),
                        'DEFINE': define
                    })

            if self.define_prefix:
                define = self.define_prefix + 'ERROR_' + name.replace(
                    ' ', '_').replace('.', '_').upper()
                self.h(
                    """\
/**
 * \\ingroup errorstrconsts
 *
 * The error name "%(fullname)s" as a QLatin1String, usable in QString requiring contexts even when
 * building with Q_NO_CAST_FROM_ASCII defined.
%(docstring)s\
 */
#define %(DEFINE)s QLatin1String("%(fullname)s")

""" % {
                        'fullname': fullname,
                        'docstring': format_docstring(error),
                        'DEFINE': define
                    })
def format_docstring(el, indent=' * ', brackets=None, maxwidth=80):
    docstring_el = None

    for x in el.childNodes:
        if x.namespaceURI == NS_TP and x.localName == 'docstring':
            docstring_el = x

    if not docstring_el:
        return ''

    lines = []

    if docstring_el.getAttribute('xmlns') == 'http://www.w3.org/1999/xhtml':
        splitted = ''.join([el.toxml() for el in docstring_el.childNodes]).strip(' ').strip('\n').split('\n')
        level = min([not match and maxint or match.end() - 1 for match in [re.match('^ *[^ ]', line) for line in splitted]])
        assert level != maxint
        lines = [line[level:].replace('\\', '\\\\') for line in splitted]
    else:
        content = xml_escape(get_descendant_text(docstring_el).replace('\n', ' ').strip())

        while content.find('  ') != -1:
            content = content.replace('  ', ' ')

        left = maxwidth - len(indent) - 1
        line = ''

        while content:
            step = (content.find(' ') + 1) or len(content)

            if step > left:
                lines.append(line)
                line = ''
                left = maxwidth - len(indent) - 1

            left = left - step
            line = line + content[:step]
            content = content[step:]

        if line:
            lines.append(line.replace('\\', '\\\\'))

    output = []

    if lines:
        if brackets:
            output.append(brackets[0])
        else:
            output.append(indent)
 
        output.append('\n')

    for line in lines:
        output.append(indent)
        output.append(line)
        output.append('\n')

    if lines and brackets:
        output.append(brackets[1])
        output.append('\n')

    return ''.join(output)