def do_signal(self, signal): name = signal.getAttribute('name') argnames, argdocstrings, argbindings = extract_arg_or_member_info( get_by_path(signal, 'arg'), self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ') self.h(""" /** * Represents the signal \\c %s on the remote object. %s\ """ % (name, format_docstring(signal, self.refs, ' * '))) for i in xrange(len(argnames)): assert argnames[ i] != None, 'Name missing from argument at index %d for signal %s' % ( i, name) if argdocstrings[i]: self.h("""\ * * \\param %s %s\ """ % (argnames[i], argdocstrings[i])) self.h("""\ */ void %s(%s); """ % (name, ', '.join([ '%s %s' % (binding.inarg, name) for binding, name in zip(argbindings, argnames) ])))
def do_val(self, val, prefix, last): name = (val.getAttribute('suffix') or val.getAttribute('name')).replace('_', '') self.h("""\ %s\ %s = %s, """ % (format_docstring(val, self.refs, indent=' * ', brackets=(' /**', ' */')), prefix + name, val.getAttribute('value')))
def do_val(self, val, prefix, last): name = (val.getAttribute('suffix') or val.getAttribute('name')).replace('_', '') self.h("""\ %s\ %s = %s, """ % (format_docstring(val, indent=' * ', brackets=( ' /**', ' */')), prefix + name, val.getAttribute('value')))
def do_flags(self, flags): singular = flags.getAttribute('singular') or \ flags.getAttribute('value-prefix') using_name = False if not singular: using_name = True singular = flags.getAttribute('name') if singular.endswith('lags'): singular = singular[:-1] if using_name and singular.endswith('s'): singular = singular[:-1] singular = singular.replace('_', '') plural = (flags.getAttribute('plural') or flags.getAttribute('name') or singular + 's').replace('_', '') self.h("""\ /** * \\ingroup flagtypeconsts * * Flag type generated from the specification. */ enum %(singular)s { """ % {'singular': singular}) flagvalues = get_by_path(flags, 'flag') for flag in flagvalues: self.do_val(flag, singular, flag == flagvalues[-1]) self.h("""\ %s = 0xffffffffU """ % ("_" + singular + "Padding")) self.h( """\ }; /** * \\typedef QFlags<%(singular)s> %(plural)s * \\ingroup flagtypeconsts * * Type representing combinations of #%(singular)s values. %(docstring)s\ */ typedef QFlags<%(singular)s> %(plural)s; Q_DECLARE_OPERATORS_FOR_FLAGS(%(plural)s) """ % { 'singular': singular, 'plural': plural, 'docstring': format_docstring(flags) })
def do_enum(self, enum): singular = enum.getAttribute('singular') or \ enum.getAttribute('name') value_prefix = enum.getAttribute('singular') or \ enum.getAttribute('value-prefix') or \ enum.getAttribute('name') if singular.endswith('lags'): singular = singular[:-1] plural = enum.getAttribute('plural') or singular + 's' singular = singular.replace('_', '') value_prefix = value_prefix.replace('_', '') vals = get_by_path(enum, 'enumvalue') self.h("""\ /** * \\enum %(singular)s * \\ingroup enumtypeconsts * * Enumerated type generated from the specification. %(docstring)s\ */ enum %(singular)s { """ % { 'singular': singular, 'docstring': format_docstring(enum) }) for val in vals: self.do_val(val, value_prefix, val == vals[-1]) self.h("""\ %s = 0xffffffffU }; """ % ("_" + singular + "Padding")) self.h( """\ /** * \\ingroup enumtypeconsts * * 1 higher than the highest valid value of %(singular)s. */ const int NUM_%(upper-plural)s = (%(last-val)s+1); """ % { 'singular': singular, 'upper-plural': plural.upper(), 'last-val': vals[-1].getAttribute('value') })
def do_prop(self, prop): name = prop.getAttribute('name') access = prop.getAttribute('access') gettername = name settername = None docstring = format_docstring(prop, self.refs, ' * ').replace('*/', '*/') sig = prop.getAttribute('type') tptype = prop.getAttributeNS(NS_TP, 'type') binding = binding_from_usage(sig, tptype, self.custom_lists, (sig, tptype) in self.externals, self.typesnamespace) if 'write' in access: settername = 'set' + name if 'read' in access: self.h(""" /** * Asynchronous getter for the remote object property \\c %(name)s of type \\c %(val)s. * %(docstring)s\ * * \\return A pending variant which will emit finished when the property has been * retrieved. */ inline Tp::PendingVariant *%(gettername)s() const { return internalRequestProperty(QLatin1String("%(name)s")); } """ % {'name' : name, 'docstring' : docstring, 'val' : binding.val, 'gettername' : 'requestProperty' + name}) if 'write' in access: self.h(""" /** * Asynchronous setter for the remote object property \\c %(name)s of type \\c %(type)s. * %(docstring)s\ * * \\return A pending operation which will emit finished when the property has been * set. */ inline Tp::PendingOperation *%(settername)s(%(type)s newValue) { return internalSetProperty(QLatin1String("%(name)s"), QVariant::fromValue(newValue)); } """ % {'name' : name, 'docstring' : docstring, 'type' : binding.val, 'name' : name, 'settername' : 'setProperty' + name})
def do_flags(self, flags): singular = flags.getAttribute('singular') or \ flags.getAttribute('value-prefix') using_name = False if not singular: using_name = True singular = flags.getAttribute('name') if singular.endswith('lags'): singular = singular[:-1] if using_name and singular.endswith('s'): singular = singular[:-1] singular = singular.replace('_', '') plural = (flags.getAttribute('plural') or flags.getAttribute('name') or singular + 's').replace('_', '') self.h("""\ /** * \\ingroup flagtypeconsts * * Flag type generated from the specification. */ enum %(singular)s { """ % {'singular' : singular}) flagvalues = get_by_path(flags, 'flag') for flag in flagvalues: self.do_val(flag, singular, flag == flagvalues[-1]) self.h("""\ %s = 0xffffffffU """ % ("_" + singular + "Padding")) self.h("""\ }; /** * \\typedef QFlags<%(singular)s> %(plural)s * \\ingroup flagtypeconsts * * Type representing combinations of #%(singular)s values. %(docstring)s\ */ typedef QFlags<%(singular)s> %(plural)s; Q_DECLARE_OPERATORS_FOR_FLAGS(%(plural)s) """ % {'singular' : singular, 'plural' : plural, 'docstring' : format_docstring(flags, self.refs)})
def do_enum(self, enum): singular = enum.getAttribute('singular') or \ enum.getAttribute('name') value_prefix = enum.getAttribute('singular') or \ enum.getAttribute('value-prefix') or \ enum.getAttribute('name') if singular.endswith('lags'): singular = singular[:-1] plural = enum.getAttribute('plural') or singular + 's' singular = singular.replace('_', '') value_prefix = value_prefix.replace('_', '') vals = get_by_path(enum, 'enumvalue') self.h("""\ /** * \\enum %(singular)s * \\ingroup enumtypeconsts * * Enumerated type generated from the specification. %(docstring)s\ */ enum %(singular)s { """ % {'singular' : singular, 'docstring' : format_docstring(enum, self.refs)}) for val in vals: self.do_val(val, value_prefix, val == vals[-1]) self.h("""\ %s = 0xffffffffU }; """ % ("_" + singular + "Padding")) self.h("""\ /** * \\ingroup enumtypeconsts * * 1 higher than the highest valid value of %(singular)s. */ const int NUM_%(upper-plural)s = (%(last-val)s+1); """ % {'singular' : singular, 'upper-plural' : plural.upper(), 'last-val' : vals[-1].getAttribute('value')})
def do_signal(self, signal): name = signal.getAttribute('name') argnames, argdocstrings, argbindings = extract_arg_or_member_info(get_by_path(signal, 'arg'), self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ') self.h(""" /** * Represents the signal \\c %s on the remote object. %s\ """ % (name, format_docstring(signal, self.refs, ' * '))) for i in xrange(len(argnames)): assert argnames[i] != None, 'Name missing from argument at index %d for signal %s' % (i, name) if argdocstrings[i]: self.h("""\ * * \\param %s %s\ """ % (argnames[i], argdocstrings[i])) self.h("""\ */ void %s(%s); """ % (name, ', '.join(['%s %s' % (binding.inarg, name) for binding, name in zip(argbindings, argnames)])))
def output_by_depinfo(self, depinfo): names, docstrings, bindings = extract_arg_or_member_info(get_by_path(depinfo.el, 'member'), self.custom_lists, self.externals, None, self.refs, ' * ', (' /**', ' */')) members = len(names) if depinfo.el.localName == 'struct': if members == 0: raise EmptyStruct(depinfo.binding.val) self.decl("""\ /** * \\struct %(name)s * \\ingroup struct %(headercmd)s\ * * Structure type generated from the specification. %(docstring)s\ */ struct %(visibility)s %(name)s { """ % { 'name' : depinfo.binding.val, 'headercmd': get_headerfile_cmd(self.realinclude, self.prettyinclude), 'docstring' : format_docstring(depinfo.el, self.refs), 'visibility': self.visibility, }) for i in xrange(members): self.decl("""\ %s\ %s %s; """ % (docstrings[i], bindings[i].val, names[i])) self.decl("""\ }; """) self.both('%s bool operator==(%s v1, %s v2)' % (self.visibility, depinfo.binding.inarg, depinfo.binding.inarg)) self.decl(';\n') self.impl(""" {""") if (bindings[0].val != 'QDBusVariant'): self.impl(""" return ((v1.%s == v2.%s)""" % (names[0], names[0])) else: self.impl(""" return ((v1.%s.variant() == v2.%s.variant())""" % (names[0], names[0])) for i in xrange(1, members): if (bindings[i].val != 'QDBusVariant'): self.impl(""" && (v1.%s == v2.%s)""" % (names[i], names[i])) else: self.impl(""" && (v1.%s.variant() == v2.%s.variant())""" % (names[i], names[i])) self.impl(""" ); } """) self.decl('inline bool operator!=(%s v1, %s v2)' % (depinfo.binding.inarg, depinfo.binding.inarg)) self.decl(""" { return !operator==(v1, v2); } """) self.both('%s QDBusArgument& operator<<(QDBusArgument& arg, %s val)' % (self.visibility, depinfo.binding.inarg)) self.decl(';\n') self.impl(""" { arg.beginStructure(); arg << %s; arg.endStructure(); return arg; } """ % ' << '.join(['val.' + name for name in names])) self.both('%s const QDBusArgument& operator>>(const QDBusArgument& arg, %s val)' % (self.visibility, depinfo.binding.outarg)) self.decl(';\n\n') self.impl(""" { arg.beginStructure(); arg >> %s; arg.endStructure(); return arg; } """ % ' >> '.join(['val.' + name for name in names])) elif depinfo.el.localName == 'mapping': if members != 2: raise MalformedMapping(depinfo.binding.val, members) realtype = 'QMap<%s, %s>' % (bindings[0].val, (bindings[1].val.endswith('>') and bindings[1].val + ' ') or bindings[1].val) self.decl("""\ /** * \\struct %s * \\ingroup mapping %s\ * * Mapping type generated from the specification. Convertible with * %s, but needed to have a discrete type in the Qt type system. %s\ */ """ % (depinfo.binding.val, get_headerfile_cmd(self.realinclude, self.prettyinclude), realtype, format_docstring(depinfo.el, self.refs))) self.decl(self.faketype(depinfo.binding.val, realtype)) else: raise WTF(depinfo.el.localName) self.to_declare.append(self.namespace + '::' + depinfo.binding.val) if depinfo.binding.array_val: self.to_declare.append('%s::%s' % (self.namespace, depinfo.binding.array_val)) self.decl("""\ /** * \\ingroup list %s\ * * Array of %s values. */ typedef %s %s; """ % (get_headerfile_cmd(self.realinclude, self.prettyinclude), depinfo.binding.val, 'QList<%s>' % depinfo.binding.val, depinfo.binding.array_val)) i = depinfo.binding.array_depth while i > 1: i -= 1 self.to_declare.append('%s::%s%s' % (self.namespace, depinfo.binding.array_val, ('List' * i))) list_of = depinfo.binding.array_val + ('List' * (i-1)) self.decl("""\ /** * \\ingroup list %s\ * * Array of %s values. */ typedef QList<%s> %sList; """ % (get_headerfile_cmd(self.realinclude, self.prettyinclude), list_of, list_of, list_of))
def do_method(self, ifacename, method): name = method.getAttribute('name') adaptee_name = to_lower_camel_case( method.getAttribute('tp:name-for-bindings')) args = get_by_path(method, 'arg') argnames, argdocstrings, argbindings = extract_arg_or_member_info( args, self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ') docstring = format_docstring(method, self.refs, ' * ').replace('*/', '*/') inargs = [] outargs = [] for i in xrange(len(args)): if args[i].getAttribute('direction') == 'out': outargs.append(i) else: inargs.append(i) assert argnames[ i] != None, 'No argument name for input argument at index %d for method %s' % ( i, name) if outargs: rettype = argbindings[outargs[0]].val else: rettype = 'void' params = [argbindings[i].inarg + ' ' + argnames[i] for i in inargs] params.append('const QDBusMessage& dbusMessage') params += [ argbindings[i].outarg + ' ' + argnames[i] for i in outargs[1:] ] params = ', '.join(params) if outargs: outargtypes = ', '.join([argbindings[i].val for i in outargs]) else: outargtypes = '' invokemethodargs = ', '.join([ 'Q_ARG(' + argbindings[i].val + ', ' + argnames[i] + ')' for i in inargs ]) inparams = [argbindings[i].val for i in inargs] inparams.append("%s::%s::%sContextPtr" % (self.namespace, ifacename, name)) normalized_adaptee_params = ','.join(inparams) adaptee_params = [ argbindings[i].inarg + ' ' + argnames[i] for i in inargs ] adaptee_params.append( 'const %(namespace)s::%(ifacename)s::%(name)sContextPtr &context' % { 'namespace': self.namespace, 'ifacename': ifacename, 'name': name }) adaptee_params = ', '.join(adaptee_params) self.h( """\ /** * Begins a call to the exported D-Bus method \\c %(name)s on this object. * * Adaptees should export this method as a Qt slot with the following signature: * void %(adaptee_name)s(%(adaptee_params)s); * * Implementations should call MethodInvocationContext::setFinished (or setFinishedWithError * accordingly) on the received \\a context object once the method has finished processing. * %(docstring)s\ * """ % { 'name': name, 'adaptee_name': adaptee_name, 'adaptee_params': adaptee_params, 'rettype': rettype, 'docstring': docstring }) for i in inargs: if argdocstrings[i]: self.h("""\ * \\param %s %s\ """ % (argnames[i], argdocstrings[i])) for i in outargs[1:]: if argdocstrings[i]: self.h("""\ * \\param %s Output parameter %s\ """ % (argnames[i], argdocstrings[i])) if outargs: self.h("""\ * \\return %s\ """ % argdocstrings[outargs[0]]) self.h("""\ */ %(rettype)s %(name)s(%(params)s); """ % { 'rettype': rettype, 'name': name, 'params': params }) self.b( """ %(rettype)s %(ifacename)s::%(name)s(%(params)s) { if (!adaptee()->metaObject()->indexOfMethod("%(adaptee_name)s(%(normalized_adaptee_params)s)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); """ % { 'rettype': rettype, 'ifacename': ifacename, 'name': name, 'adaptee_name': adaptee_name, 'normalized_adaptee_params': normalized_adaptee_params, 'params': params, }) if rettype != 'void': self.b("""\ return %(rettype)s(); """ % {'rettype': rettype}) else: self.b("""\ return; """) self.b("""\ } %(name)sContextPtr ctx = %(name)sContextPtr( new Tp::MethodInvocationContext< %(outargtypes)s >(dbusConnection(), dbusMessage)); """ % { 'name': name, 'outargtypes': outargtypes, }) if invokemethodargs: self.b( """\ QMetaObject::invokeMethod(adaptee(), "%(adaptee_name)s", %(invokemethodargs)s, Q_ARG(%(namespace)s::%(ifacename)s::%(name)sContextPtr, ctx)); """ % { 'namespace': self.namespace, 'ifacename': ifacename, 'name': name, 'adaptee_name': adaptee_name, 'invokemethodargs': invokemethodargs, }) else: self.b( """\ QMetaObject::invokeMethod(adaptee(), "%(lname)s", Q_ARG(%(namespace)s::%(ifacename)s::%(name)sContextPtr, ctx)); """ % { 'namespace': self.namespace, 'ifacename': ifacename, 'name': name, 'lname': (name[0].lower() + name[1:]), }) if rettype != 'void': self.b("""\ return %(rettype)s(); """ % {'rettype': rettype}) self.b("}\n")
def do_prop(self, ifacename, prop): name = prop.getAttribute('name') adaptee_name = to_lower_camel_case( prop.getAttribute('tp:name-for-bindings')) access = prop.getAttribute('access') gettername = name settername = None if 'write' in access: settername = 'Set' + name docstring = format_docstring(prop, self.refs, ' * ').replace('*/', '*/') sig = prop.getAttribute('type') tptype = prop.getAttributeNS(NS_TP, 'type') binding = binding_from_usage(sig, tptype, self.custom_lists, (sig, tptype) in self.externals, self.typesnamespace) if 'read' in access: self.h( """\ /** * Return the value of the exported D-Bus object property \\c %(name)s of type \\c %(type)s. * * Adaptees should export this property as a Qt property named * '%(adaptee_name)s' with type %(type)s. * %(docstring)s\ * * \\return The value of exported property \\c %(name)s. */ %(type)s %(gettername)s() const; """ % { 'name': name, 'adaptee_name': adaptee_name, 'docstring': docstring, 'type': binding.val, 'gettername': gettername, }) self.b( """ %(type)s %(ifacename)s::%(gettername)s() const { return qvariant_cast< %(type)s >(adaptee()->property("%(adaptee_name)s")); } """ % { 'type': binding.val, 'ifacename': ifacename, 'gettername': gettername, 'adaptee_name': adaptee_name, }) if 'write' in access: self.h( """\ /** * Set the value of the exported D-Bus object property \\c %(name)s of type \\c %(type)s. * * Adaptees should export this property as a writable Qt property named * '%(adaptee_name)s' with type %(type)s. * %(docstring)s\ */ void %(settername)s(const %(type)s &newValue); """ % { 'name': name, 'adaptee_name': adaptee_name, 'docstring': docstring, 'settername': settername, 'type': binding.val, }) self.b( """ void %(ifacename)s::%(settername)s(const %(type)s &newValue) { adaptee()->setProperty("%(adaptee_name)s", qVariantFromValue(newValue)); } """ % { 'ifacename': ifacename, 'settername': settername, 'type': binding.val, 'adaptee_name': adaptee_name, })
def output_by_depinfo(self, depinfo): names, docstrings, bindings = extract_arg_or_member_info( get_by_path(depinfo.el, 'member'), self.custom_lists, self.externals, None, self.refs, ' * ', (' /**', ' */')) members = len(names) if depinfo.el.localName == 'struct': if members == 0: raise EmptyStruct(depinfo.binding.val) self.decl( """\ /** * \\struct %(name)s * \\ingroup struct %(headercmd)s\ * * Structure type generated from the specification. %(docstring)s\ */ struct %(visibility)s %(name)s { """ % { 'name': depinfo.binding.val, 'headercmd': get_headerfile_cmd(self.realinclude, self.prettyinclude), 'docstring': format_docstring(depinfo.el, self.refs), 'visibility': self.visibility, }) for i in xrange(members): self.decl("""\ %s\ %s %s; """ % (docstrings[i], bindings[i].val, names[i])) self.decl("""\ }; """) self.both('%s bool operator==(%s v1, %s v2)' % (self.visibility, depinfo.binding.inarg, depinfo.binding.inarg)) self.decl(';\n') self.impl(""" {""") if (bindings[0].val != 'QDBusVariant'): self.impl(""" return ((v1.%s == v2.%s)""" % (names[0], names[0])) else: self.impl(""" return ((v1.%s.variant() == v2.%s.variant())""" % (names[0], names[0])) for i in xrange(1, members): if (bindings[i].val != 'QDBusVariant'): self.impl(""" && (v1.%s == v2.%s)""" % (names[i], names[i])) else: self.impl(""" && (v1.%s.variant() == v2.%s.variant())""" % (names[i], names[i])) self.impl(""" ); } """) self.decl('inline bool operator!=(%s v1, %s v2)' % (depinfo.binding.inarg, depinfo.binding.inarg)) self.decl(""" { return !operator==(v1, v2); } """) self.both( '%s QDBusArgument& operator<<(QDBusArgument& arg, %s val)' % (self.visibility, depinfo.binding.inarg)) self.decl(';\n') self.impl(""" { arg.beginStructure(); arg << %s; arg.endStructure(); return arg; } """ % ' << '.join(['val.' + name for name in names])) self.both( '%s const QDBusArgument& operator>>(const QDBusArgument& arg, %s val)' % (self.visibility, depinfo.binding.outarg)) self.decl(';\n\n') self.impl(""" { arg.beginStructure(); arg >> %s; arg.endStructure(); return arg; } """ % ' >> '.join(['val.' + name for name in names])) elif depinfo.el.localName == 'mapping': if members != 2: raise MalformedMapping(depinfo.binding.val, members) realtype = 'QMap<%s, %s>' % (bindings[0].val, (bindings[1].val.endswith('>') and bindings[1].val + ' ') or bindings[1].val) self.decl("""\ /** * \\struct %s * \\ingroup mapping %s\ * * Mapping type generated from the specification. Convertible with * %s, but needed to have a discrete type in the Qt type system. %s\ */ """ % (depinfo.binding.val, get_headerfile_cmd(self.realinclude, self.prettyinclude), realtype, format_docstring(depinfo.el, self.refs))) self.decl(self.faketype(depinfo.binding.val, realtype)) else: raise WTF(depinfo.el.localName) self.to_declare.append(self.namespace + '::' + depinfo.binding.val) if depinfo.binding.array_val: self.to_declare.append('%s::%s' % (self.namespace, depinfo.binding.array_val)) self.decl("""\ /** * \\ingroup list %s\ * * Array of %s values. */ typedef %s %s; """ % (get_headerfile_cmd(self.realinclude, self.prettyinclude), depinfo.binding.val, 'QList<%s>' % depinfo.binding.val, depinfo.binding.array_val)) i = depinfo.binding.array_depth while i > 1: i -= 1 self.to_declare.append('%s::%s%s' % (self.namespace, depinfo.binding.array_val, ('List' * i))) list_of = depinfo.binding.array_val + ('List' * (i - 1)) self.decl("""\ /** * \\ingroup list %s\ * * Array of %s values. */ typedef QList<%s> %sList; """ % (get_headerfile_cmd(self.realinclude, self.prettyinclude), list_of, list_of, list_of))
def do_prop(self, prop): name = prop.getAttribute('name') access = prop.getAttribute('access') gettername = name settername = None docstring = format_docstring(prop, self.refs, ' * ').replace('*/', '*/') sig = prop.getAttribute('type') tptype = prop.getAttributeNS(NS_TP, 'type') binding = binding_from_usage(sig, tptype, self.custom_lists, (sig, tptype) in self.externals, self.typesnamespace) if 'write' in access: settername = 'set' + name if 'read' in access: self.h( """ /** * Asynchronous getter for the remote object property \\c %(name)s of type \\c %(val)s. * %(docstring)s\ * * \\return A pending variant which will emit finished when the property has been * retrieved. */ inline Tp::PendingVariant *%(gettername)s() const { return internalRequestProperty(QLatin1String("%(name)s")); } """ % { 'name': name, 'docstring': docstring, 'val': binding.val, 'gettername': 'requestProperty' + name }) if 'write' in access: self.h( """ /** * Asynchronous setter for the remote object property \\c %(name)s of type \\c %(type)s. * %(docstring)s\ * * \\return A pending operation which will emit finished when the property has been * set. */ inline Tp::PendingOperation *%(settername)s(%(type)s newValue) { return internalSetProperty(QLatin1String("%(name)s"), QVariant::fromValue(newValue)); } """ % { 'name': name, 'docstring': docstring, 'type': binding.val, 'name': name, 'settername': 'setProperty' + name })
def do_method(self, method): name = method.getAttribute('name') args = get_by_path(method, 'arg') argnames, argdocstrings, argbindings = extract_arg_or_member_info( args, self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ') inargs = [] outargs = [] for i in xrange(len(args)): if args[i].getAttribute('direction') == 'out': outargs.append(i) else: inargs.append(i) assert argnames[ i] != None, 'No argument name for input argument at index %d for method %s' % ( i, name) rettypes = ', '.join([argbindings[i].val for i in outargs]) params = ', '.join( [argbindings[i].inarg + ' ' + argnames[i] for i in inargs]) if params: params += ', int timeout = -1' else: params = 'int timeout = -1' self.h(""" /** * Begins a call to the D-Bus method \\c %s on the remote object. %s\ * * Note that \\a timeout is ignored as of now. It will be used once * http://bugreports.qt.nokia.com/browse/QTBUG-11775 is fixed. * """ % (name, format_docstring(method, self.refs, ' * '))) for i in inargs: if argdocstrings[i]: self.h("""\ * * \\param %s %s\ """ % (argnames[i], argdocstrings[i])) self.h("""\ * \\param timeout The timeout in milliseconds. """) for i in outargs: if argdocstrings[i]: self.h("""\ * * \\return %s\ """ % argdocstrings[i]) self.h("""\ */ inline QDBusPendingReply<%(rettypes)s> %(name)s(%(params)s) { if (!invalidationReason().isEmpty()) { return QDBusPendingReply<%(rettypes)s>(QDBusMessage::createError( invalidationReason(), invalidationMessage() )); } """ % { 'rettypes': rettypes, 'name': name, 'params': params }) if inargs: self.h(""" QDBusMessage callMessage = QDBusMessage::createMethodCall(this->service(), this->path(), this->staticInterfaceName(), QLatin1String("%s")); callMessage << %s; return this->connection().asyncCall(callMessage, timeout); } """ % (name, ' << '.join( ['QVariant::fromValue(%s)' % argnames[i] for i in inargs]))) else: self.h(""" QDBusMessage callMessage = QDBusMessage::createMethodCall(this->service(), this->path(), this->staticInterfaceName(), QLatin1String("%s")); return this->connection().asyncCall(callMessage, timeout); } """ % name)
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, self.refs), '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, self.refs), 'DEFINE' : define})
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 do_method(self, method): name = method.getAttribute('name') args = get_by_path(method, 'arg') argnames, argdocstrings, argbindings = extract_arg_or_member_info(args, self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ') inargs = [] outargs = [] for i in xrange(len(args)): if args[i].getAttribute('direction') == 'out': outargs.append(i) else: inargs.append(i) assert argnames[i] != None, 'No argument name for input argument at index %d for method %s' % (i, name) rettypes = ', '.join([argbindings[i].val for i in outargs]) params = ', '.join([argbindings[i].inarg + ' ' + argnames[i] for i in inargs]) if params: params += ', int timeout = -1' else: params = 'int timeout = -1' self.h(""" /** * Begins a call to the D-Bus method \\c %s on the remote object. %s\ * * Note that \\a timeout is ignored as of now. It will be used once * http://bugreports.qt.nokia.com/browse/QTBUG-11775 is fixed. * """ % (name, format_docstring(method, self.refs, ' * '))) for i in inargs: if argdocstrings[i]: self.h("""\ * * \\param %s %s\ """ % (argnames[i], argdocstrings[i])) self.h("""\ * \\param timeout The timeout in milliseconds. """) for i in outargs: if argdocstrings[i]: self.h("""\ * * \\return %s\ """ % argdocstrings[i]) self.h("""\ */ inline QDBusPendingReply<%(rettypes)s> %(name)s(%(params)s) { if (!invalidationReason().isEmpty()) { return QDBusPendingReply<%(rettypes)s>(QDBusMessage::createError( invalidationReason(), invalidationMessage() )); } """ % {'rettypes' : rettypes, 'name' : name, 'params' : params}) if inargs: self.h(""" QDBusMessage callMessage = QDBusMessage::createMethodCall(this->service(), this->path(), this->staticInterfaceName(), QLatin1String("%s")); callMessage << %s; return this->connection().asyncCall(callMessage, timeout); } """ % (name, ' << '.join(['QVariant::fromValue(%s)' % argnames[i] for i in inargs]))) else: self.h(""" QDBusMessage callMessage = QDBusMessage::createMethodCall(this->service(), this->path(), this->staticInterfaceName(), QLatin1String("%s")); return this->connection().asyncCall(callMessage, timeout); } """ % name)
def do_prop(self, ifacename, prop): name = prop.getAttribute('name') adaptee_name = to_lower_camel_case(prop.getAttribute('tp:name-for-bindings')) access = prop.getAttribute('access') gettername = name settername = None if 'write' in access: settername = 'Set' + name docstring = format_docstring(prop, self.refs, ' * ').replace('*/', '*/') sig = prop.getAttribute('type') tptype = prop.getAttributeNS(NS_TP, 'type') binding = binding_from_usage(sig, tptype, self.custom_lists, (sig, tptype) in self.externals, self.typesnamespace) if 'read' in access: self.h("""\ /** * Return the value of the exported D-Bus object property \\c %(name)s of type \\c %(type)s. * * Adaptees should export this property as a Qt property named * '%(adaptee_name)s' with type %(type)s. * %(docstring)s\ * * \\return The value of exported property \\c %(name)s. */ %(type)s %(gettername)s() const; """ % {'name': name, 'adaptee_name': adaptee_name, 'docstring': docstring, 'type': binding.val, 'gettername': gettername, }) self.b(""" %(type)s %(ifacename)s::%(gettername)s() const { return qvariant_cast< %(type)s >(adaptee()->property("%(adaptee_name)s")); } """ % {'type': binding.val, 'ifacename': ifacename, 'gettername': gettername, 'adaptee_name': adaptee_name, }) if 'write' in access: self.h("""\ /** * Set the value of the exported D-Bus object property \\c %(name)s of type \\c %(type)s. * * Adaptees should export this property as a writable Qt property named * '%(adaptee_name)s' with type %(type)s. * %(docstring)s\ */ void %(settername)s(const %(type)s &newValue); """ % {'name': name, 'adaptee_name': adaptee_name, 'docstring': docstring, 'settername': settername, 'type': binding.val, }) self.b(""" void %(ifacename)s::%(settername)s(const %(type)s &newValue) { adaptee()->setProperty("%(adaptee_name)s", qVariantFromValue(newValue)); } """ % {'ifacename': ifacename, 'settername': settername, 'type': binding.val, 'adaptee_name': adaptee_name, })
def do_method(self, ifacename, method): name = method.getAttribute('name') adaptee_name = to_lower_camel_case(method.getAttribute('tp:name-for-bindings')) args = get_by_path(method, 'arg') argnames, argdocstrings, argbindings = extract_arg_or_member_info(args, self.custom_lists, self.externals, self.typesnamespace, self.refs, ' * ') docstring = format_docstring(method, self.refs, ' * ').replace('*/', '*/') inargs = [] outargs = [] for i in xrange(len(args)): if args[i].getAttribute('direction') == 'out': outargs.append(i) else: inargs.append(i) assert argnames[i] != None, 'No argument name for input argument at index %d for method %s' % (i, name) if outargs: rettype = argbindings[outargs[0]].val else: rettype = 'void' params = [argbindings[i].inarg + ' ' + argnames[i] for i in inargs] params.append('const QDBusMessage& dbusMessage') params += [argbindings[i].outarg + ' ' + argnames[i] for i in outargs[1:]] params = ', '.join(params) if outargs: outargtypes = ', '.join([argbindings[i].val for i in outargs]) else: outargtypes = '' invokemethodargs = ', '.join(['Q_ARG(' + argbindings[i].val + ', ' + argnames[i] + ')' for i in inargs]) inparams = [argbindings[i].val for i in inargs] inparams.append("%s::%s::%sContextPtr" % (self.namespace, ifacename, name)) normalized_adaptee_params = ','.join(inparams) adaptee_params = [argbindings[i].inarg + ' ' + argnames[i] for i in inargs] adaptee_params.append('const %(namespace)s::%(ifacename)s::%(name)sContextPtr &context' % {'namespace': self.namespace, 'ifacename': ifacename, 'name': name}) adaptee_params = ', '.join(adaptee_params) self.h("""\ /** * Begins a call to the exported D-Bus method \\c %(name)s on this object. * * Adaptees should export this method as a Qt slot with the following signature: * void %(adaptee_name)s(%(adaptee_params)s); * * Implementations should call MethodInvocationContext::setFinished (or setFinishedWithError * accordingly) on the received \\a context object once the method has finished processing. * %(docstring)s\ * """ % {'name': name, 'adaptee_name': adaptee_name, 'adaptee_params': adaptee_params, 'rettype': rettype, 'docstring': docstring }) for i in inargs: if argdocstrings[i]: self.h("""\ * \\param %s %s\ """ % (argnames[i], argdocstrings[i])) for i in outargs[1:]: if argdocstrings[i]: self.h("""\ * \\param %s Output parameter %s\ """ % (argnames[i], argdocstrings[i])) if outargs: self.h("""\ * \\return %s\ """ % argdocstrings[outargs[0]]) self.h("""\ */ %(rettype)s %(name)s(%(params)s); """ % {'rettype': rettype, 'name': name, 'params': params }) self.b(""" %(rettype)s %(ifacename)s::%(name)s(%(params)s) { if (!adaptee()->metaObject()->indexOfMethod("%(adaptee_name)s(%(normalized_adaptee_params)s)") == -1) { dbusConnection().send(dbusMessage.createErrorReply(TP_QT_ERROR_NOT_IMPLEMENTED, QLatin1String("Not implemented"))); """ % {'rettype': rettype, 'ifacename': ifacename, 'name': name, 'adaptee_name': adaptee_name, 'normalized_adaptee_params': normalized_adaptee_params, 'params': params, }) if rettype != 'void': self.b("""\ return %(rettype)s(); """ % {'rettype': rettype}) else: self.b("""\ return; """) self.b("""\ } %(name)sContextPtr ctx = %(name)sContextPtr( new Tp::MethodInvocationContext< %(outargtypes)s >(dbusConnection(), dbusMessage)); """ % {'name': name, 'outargtypes': outargtypes, }) if invokemethodargs: self.b("""\ QMetaObject::invokeMethod(adaptee(), "%(adaptee_name)s", %(invokemethodargs)s, Q_ARG(%(namespace)s::%(ifacename)s::%(name)sContextPtr, ctx)); """ % {'namespace': self.namespace, 'ifacename': ifacename, 'name': name, 'adaptee_name': adaptee_name, 'invokemethodargs': invokemethodargs, }) else: self.b("""\ QMetaObject::invokeMethod(adaptee(), "%(lname)s", Q_ARG(%(namespace)s::%(ifacename)s::%(name)sContextPtr, ctx)); """ % {'namespace': self.namespace, 'ifacename': ifacename, 'name': name, 'lname': (name[0].lower() + name[1:]), }) if rettype != 'void': self.b("""\ return %(rettype)s(); """ % {'rettype': rettype}) self.b("}\n")