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"))
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"))
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)